2011-06-07 29 views
5

Bir listeyi döngülemek ve gereksinimi karşılıyorsa öğeyi kaldırmak istiyorum. Aynı zamanda, kaldırılan öğeyi dönüştürürüm ve dönüşüm sonucunu başka bir listeye eklerim.Aşağıdaki mantığı uygulamak için pythonik yol ne olmalıdır?

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) 

kod mantığını uygulamak için daha iyi bir yol yoktur, bu yüzden düz ileri değil:

Şu anda, aşağıdaki kodla mantığı yukarıda uyguladık?

+1

Ben farklı yazardım iken (Kedi Artı Plus'ın yolu muhtemelen), senin yaklaşımı yanlış bir şey görmüyorum. –

cevap

6

Bunu yalnızca anlamalarla yapabilirsiniz.

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] 
+0

Bunun, 'another_list' içindeki öğelerin sırasını değiştirdiğini unutmayın. –

+0

Sığ kopya zamanı mı? Bölüm fikri için [:] –

1
Sen setini önlemek için bu yapabilirdi

: pythonic yaklaşık

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

mylist[:] = part(mylist, another_list) 
0
>>> 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 
3

Emin değilim, ama piton Haskell benzer bir partition işlevi vardı (veya eğer basit tek kendini yazabilirsiniz), kod orijinal listesinde iki kez (Cat Plus 'çözümünde olduğu gibi) yineleme gerekmez.

Ben böyle bir şey aşağıdakilerden hangisini kullanırsınız:

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

+1 –

1

Kendinizin veya another_list ters istemeyebilirsiniz olabilir (veya bir deque ve appendleft kullanabilirsiniz) sonra bu

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

yapabilirdi

0
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]] 
0

Diğer d'ye benzer bir şeye ihtiyacım vardı ay:

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) 

Ya da bu tek geçişli varyasyonu:

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) 
İlgili konular