Двойной цикл для whois.py

Я использую словарь с идентификатором в качестве ключа и именами в качестве значений. То, что я пытаюсь сделать, это получить имена в значениях, которые имеют одинаковое имя в них, и поместить их в список. Например, с именем tim:

{'id 1': ['timmeh', 'user543', 'tim'], 'id 2': ['tim', 'timmeh', '!anon0543']}
whois_list = ['timmeh', 'user543', 'tim', '!anon0543']

Бот добавит имена, которые еще не вошли в список. Это код для выполнения этого примера:

def who(name):
 whois_list = []
 if not any(l for l in whois.whoisDB.values() if name.lower() in l):
 return 'No alias found for <b>%s</b>." % name.title()
 else:
 for l in whois.whoisDB.values():
 if name.lower() in l:
 for names in l:
 if names not in whois_list
 whois_list.append(names)
 return "Possible alias found for <b>%s</b>: %s" % (name.title(), whois_list)

Проблема в том, что я не хочу иметь двойной цикл в этом коде, но я не уверен, как это сделать, если это возможно.

1 ответ

Логически эквивалентное, но более короткое и более эффективное решение заключается в использовании наборов вместо списков.

Ваш самый внутренний для цикла просто расширяет whois_list с каждым не дублирующимся именем в l. Если вы изначально определить whois_list = set([]), то вы можете заменить три линии внутренней for циклы с:

whois_list = whois_list.union(l)

Например,

>>> a = set([1,2,3])
>>> a = a.union([3,4,5])
>>> a
set([1, 2, 3, 4, 5])

Вы заметите, a распечатки немного отличаются друг от друга, что указывает на то, что это set вместо списка. Если это проблема, вы можете преобразовать ее прямо перед вашим оператором return как в

>>> a = list(a)
>>> a
[1, 2, 3, 4, 5]

licensed under cc by-sa 3.0 with attribution.