开发者

What should be the pythonic way to implement following logic?

I would like to loop a list and remove element if it meets the requirement. At the same time, I would transform the removed element and add the transformation result to another list.

Right now, I have implemented ab开发者_StackOverflow社区ove logic by following code:

delete_set = set([])

for item in my_list:
   if meet_requirement(item):
      another_list.append = transform(item)
      delete_set.add(item)

my_list = filter(lambda x:x not in delete_set, my_list)

The code is not so straight-forward, is there a better way to implement the logic?


You could do this with comprehensions only.

delete_set = set(I for I in my_list if meet_requirement(I))
another_list.extend(transform(I) for I in delete_set)
# or extend(transform(I) for I in my_list if I in delete_set), if duplicates/order matter
my_list = [I for I in my_list if I not in delete_set]


Not sure about pythonic, but if python had a partition function similar to haskell (or you could write a simple one yourself), the code wouldn't need to iterate over the original list twice (as in Cat Plus' solution).

I would use something like the following:

new_my_list, deleted_list = partition(my_list, meet_requirement)
deleted_list = [transform(e) for e in deleted_list]


you could do this

for i in reversed(xrange(len(my_list))):
    if meet_requirement(my_list[i]):
        another_list.append(transform(my_list.pop(i)))

then you might or might not want to reverse another_list (or you can use a deque and appendleft)


You could do this to avoid the set:

def part(items, others):
    for item in items:
        if meet_requirement(item):
            others.append(item)
        else:
            yield item

mylist[:] = part(mylist, another_list)


>>> another_list = []
>>> new_list = []
>>> 
>>> for item in my_list:
...     (another_list if meet_requirement(item) else new_list).append(item)
... 
>>> another_list = map(transform, another_list)
>>> my_list = new_list


zipped = zip(*[(item, transform(item)) for item in my_list \
                                                if meet_requirement(item)])
another_list = zipped[1]
my_list = [item for item in my_list if item not in zipped[0]]


I needed something similar the other day:

def partition(pred, iterable):
    result = ([], [])
    for each in iterable:
        result[pred(each)].append(each)
    return result

xs = some_list    
ys, xs[:] = partition(meet_some_requirement, xs)
ys = map(do_some_transformation, ys)

Or this one-pass variation:

def partition_and_transform(pred, iterable, *transform):
    result = ([], [])
    for each in iterable:
        v = pred(each)
        result[v].append(transform[v](each))
    return result

ys, xs[:] = partition_and_transform(meet_some_reqirement, xs, do_some_transformation, lambda x:x)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜