2013-05-22 2 views
1

Привет У меня есть список списков, и мне нужно сравнить значение каждого списка с другим, извлеченным из файла XML. Структура похожа на это:Сравните два списка в python и распечатайте вывод

[('example', '123', 'foo', 'bar'), ('example2', '456', 'foo', 'bar'), ...] 

Мне нужно сравнить второе значение каждого списка со значениями в XML:

for item in main_list: 
    for child in xml_data: 
     if item[4] == child.get('value'): 
      print item[4] 

Проблема заключается в том, что main_list имеет огромную сумму строк (1000+), и это, умноженное на значения из xml (100+), приводит к тому, что многие итерации становятся этим методом неэффективными.

Есть ли способ сделать это эффективно?

С уважением.

ответ

6

Проверка членства в наборе будет значительно быстрее, чем вручную переборе и проверки:

children = {child.get('value') for child in xml_data} 
for item in main_list: 
    if item[4] in children: 
     print(item[4]) 

Здесь мы построим множество с помощью простого set comprehension.

Обратите внимание, что может стоить заменить данные, находящиеся в наборе, - если main_list длиннее, будет более эффективным создание набора этих данных.

items = {item[4] for item in main_list} 
for child in xml_data: 
    value = child.get('value') 
    if value in items: 
     print(value) 

Они оба обрабатывают данные только один раз, а не каждый раз, когда делается чек.

Обратите внимание, что набор будет не обрабатывать повторяющиеся значения или порядок на заданной стороне - если это важно, это неверное решение. Эта версия будет использовать только порядок/дубликаты из данных, которые вы повторяете. Если это недопустимо, вы можете обработать данные заранее и использовать itertools.product() для более быстрой итерации.

items = [item[4] for item in main_list] 
children = [child.get('value') for child in xml_data] 

for item, child in itertools.product(items, children): 
    if item == child: 
     print(item) 

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

for item in ({child.get('value') for child in xml_data} & 
      {item[4] for item in main_list}): 
    print(item) 
+0

Если мы действительно не все равно о дубликатах, почему бы не сделать * оба * набора и пересечь? –

+0

@KarlKnechtel Yup, это зависит от варианта использования. Я добавлю, что в. –

+0

Спасибо, за ответ, теперь он работает намного быстрее. Я использовал второе решение и отлично подходит для своего дела. С уважением – Nucklear

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