2011-01-25 26 views
14

tôi có ba collection.deques và những gì tôi cần làm là để lặp qua mỗi trong số họ và thực hiện các hành động tương tự:Một cách thanh lịch và nhanh chóng để liên tục lặp qua hai hoặc nhiều thùng chứa bằng Python?

for obj in deque1: 
    some_action(obj) 

for obj in deque2: 
    some_action(obj) 

for obj in deque3: 
    some_action(obj) 

Tôi đang tìm kiếm một số chức năng XXX mà lý tưởng sẽ cho phép tôi viết:

for obj in XXX(deque1, deque2, deque3): 
    some_action(obj) 

Điều quan trọng ở đây là XXX phải đủ hiệu quả - không cần sao chép hoặc âm thầm sử dụng dải ô(), v.v ... Tôi đã tìm thấy nó trong các hàm dựng sẵn nhưng tôi không thấy gì tương tự nó quá xa.

Có điều gì đã có trong Python hoặc tôi phải tự viết một hàm cho chính mình không?

+0

Bạn đã xem xét chức năng zip? – Ikke

+0

AFAIK hàm zip() không phải là những gì tôi cần ở đây. – izhak

+0

Đối tượng không có ý nghĩa với tôi vì vậy tôi đã thay đổi "do đó" thành "liên tục". Xin vui lòng rollback nếu tôi chỉ là không biết gì! –

Trả lời

19

Tùy thuộc vào thứ tự những gì bạn muốn để xử lý các mục:

import itertools 

for items in itertools.izip(deque1, deque2, deque3): 
    for item in items: 
     some_action(item) 

for item in itertools.chain(deque1, deque2, deque3): 
    some_action(item) 

tôi muốn khuyên bạn nên làm điều này để tránh cứng mã hóa deques thực tế hoặc số deques:

deques = [deque1, deque2, deque3] 
for item in itertools.chain(*deques): 
    some_action(item) 

Để minh họa sự khác biệt theo thứ tự của các phương pháp trên:

>>> a = range(5) 
>>> b = range(5) 
>>> c = range(5) 
>>> d = [a, b, c] 
>>> 
>>> for items in itertools.izip(*d): 
...  for item in items: 
...   print item, 
... 
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 
>>> 
>>> for item in itertools.chain(*d): 
...  print item, 
... 
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 
>>> 
12

Câu trả lời là trong itertools

itertools.chain (* iterables)

Make an iterator that returns elements from the first iterable until 

nó kiệt sức, rồi tiến tới tiếp theo iterable, cho đến khi tất cả các iterables là kiệt sức. Được sử dụng để xử lý chuỗi liên tiếp dưới dạng một chuỗi đơn lẻ . Tương đương với:

def chain(*iterables): 
     # chain('ABC', 'DEF') --> A B C D E F 
     for it in iterables: 
      for element in it: 
       yield element 
+2

'itertools' không' iterutils' – FogleBird

+0

Cảm ơn, đã cập nhật. – Drakosha

2

Làm thế nào về zip?

for obj in zip(deque1, deque2, deque3): 
    for sub_obj in obj: 
     some_action(sub_obj) 
4

Sử dụng itertools.chain(deque1, deque2, deque3)

0

Chấp nhận một loạt các iterables, và mang lại các nội dung cho mỗi người trong số họ theo thứ tự.

def XXX(*lists): 
    for aList in lists: 
     for item in aList: 
     yield item 



l1 = [1, 2, 3, 4] 
l2 = ['a', 'b', 'c'] 
l3 = [1.0, 1.1, 1.2] 

for item in XXX(l1, l2, l3): 
    print item 

1 
2 
3 
4 
a 
b 
c 
1.0 
1.1 
1.2 
1

Dường như bạn muốn tôi tertools.chain:

"Make một iterator trả về các yếu tố từ iterable đầu tiên cho đến khi nó được sử dụng hết, rồi tiến tới iterable tiếp theo, cho đến khi tất cả các iterables đang cạn kiệt. Được sử dụng để xử lý chuỗi liên tiếp dưới dạng một chuỗi đơn. "

1

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, thì bạn có thể sử dụng map với đối số đầu tiên được đặt thành Không, và tất cả đối số khác làm danh sách của bạn để lặp lại.

E.g (từ lời nhắc iPython, nhưng bạn nhận được ý tưởng):

In [85]: p = [1,2,3,4] 

In [86]: q = ['a','b','c','d'] 

In [87]: f = ['Hi', 'there', 'world', '.'] 

In [88]: for i,j,k in map(None, p,q,f): 
    ....:  print i,j,k 
    ....: 
    ....: 
1 a Hi 
2 b there 
3 c world 
4 d . 
5

Gọi cho tôi là điên, nhưng tại sao lại sử dụng các công cụ được cho là cần thiết? Có vấn đề gì với:

def perform_func_on_each_object_in_each_of_multiple_containers(func, containers): 
    for container in containers: 
     for obj in container: 
      func(obj) 

perform_func_on_each_object_in_each_of_multiple_containers(some_action, (deque1, deque2, deque3) 

Thậm chí còn điên rồ hơn: bạn có thể sẽ sử dụng điều này một lần. Tại sao không chỉ làm:

for d in (deque1, deque2, deque3): 
    for obj in d: 
     some_action(obj) 

gì đang xảy ra ở đó là ngay lập tức rõ ràng mà không cần phải nhìn vào mã/docs cho hàm dài tên hoặc phải tìm kiếm các tài liệu cho itertools.something()

+0

Tại sao tái tạo lại bánh xe? Đây là cái gì đó xuất hiện rất nhiều. –

1

Tôi chỉ cần làm điều này:

for obj in deque1 + deque2 + deque3: 
some_action(obj) 
Các vấn đề liên quan