2013-04-05 5 views
0

Я пытаюсь сравнить несколько списков. Однако списки не являются ярлыками ... как правило. Я использую цикл while, чтобы каждый раз создавать новый список и соответствующим образом маркировать их. Так, например, если цикл while работает 3 раза, он сделает List1 a List2 и List3. Вот фрагмент кода для создания списка.Сравнение нескольких списков Python

for link in links: 
    print('*', link.text) 
    locals()['list{}'.format(str(i))].append(link.text) 

Так что я хочу, чтобы сравнить каждый список для строк, которые находятся в них, но я хочу, чтобы сравнить все списки сразу затем распечатать общие строки.

Мне кажется, что я буду использовать что-то подобное, но я не уверен на 100%.

lists = [list1, list2, list3, list4, list5, list6, list7, list8, list9, list10] 
common = list(set().union(*lists).intersection(Keyword)) 
+3

Это целые анонимные 'местные жители()' бизнес противный. В этом нет необходимости. Если вам действительно нужны метки, связанные с чем-то, используя 'dict', но это похоже, что вы создаете список списков – jdi

+2

Я также не понимаю, как использовать ярлык. Какая вам нужна произвольная метка «listN»? – jdi

ответ

1

У вас есть несколько вариантов,

вариант а)

использование itertools получить декартово произведение, это очень приятно, потому что его итератора

a = ["A", "B", "C"] 
b = ["A","C"] 
c = ["C","D","E"] 

for aval,bval,cval in itertools.product(a,b,c): 
    if aval == bval and bval == cval: 
     print aval 

вариант б)

Использовать наборы (рекомендуется):

all_lists = [] 
# insert your while loop X times 
for lst in lists:   # This is my guess of your loop running. 
    currentList = map(lambda x: x.link, links) 
    all_lists.append(currentList) # O(1) operation 

result_set = set() 
if len(all_lists)>1: 
     result_set = set(all_lists[0]).intersection(*all_lists[1:]) 
else: 
     result_set = set(all_lists[0]) 

Используя наборы, однако, будет быстрее

2

Вместо непосредственного изменения locals() (как правило, не очень хорошая идея), использовать defaultdict в качестве контейнера. Эта структура данных позволяет вам создавать новые пары ключ-значение «на лету», а не полагаться на метод, который в какой-то момент обязательно приведет к NameError.

from collections import defaultdict 

i = ... 

link_lists = defaultdict(list) 
for link in links: 
    print('*', link.text) 
    link_lists[i].append(link.text) 

Для find the intersection всех списков:

all_lists = list(link_lists.values()) 
common_links = set(all_lists[0]).intersection(*all_lists[1:]) 

В Python 2.6+, вы можете передать несколько итерируемых к set.intersection. Вот что здесь делают звезды-арги.


Вот пример того, как пересечение будет работать:

>>> from collections import defaultdict 
>>> c = defaultdict(list) 
>>> c[9].append("a") 
>>> c[0].append("b") 
>>> all = list(c.values()) 
>>> set(all[0]).intersection(*all[1:]) 
set() 
>>> c[0].append("a") 
>>> all = list(c.values()) 
>>> set(all[0]).intersection(*all[1:]) 
{'a'} 
+0

Я использую 3.3, и я все время получаю ошибку TypeError: объект «dict_values» не поддерживает индексирование. Это происходит из части common_links. – user1985351

+0

@ user1985351: Только что обновил код. Python 3. '.values ​​()' возвращает представление значений словаря, а не моментальный снимок его значений во время вызова '.values ​​()'. Мы можем преобразовать этот объект вида в список, используя 'list'. –

+0

Хорошо, ошибка исчезла. Теперь, когда я запускаю программу, когда я вызываю 'print (common_links)', он возвращает только 'set()' – user1985351

Смежные вопросы