Это относительно простой, но более острый вопрос о том, как писать наиболее сжатый цикл if/any/for, который выполняет то, что мне нужно. Я новичок в Python и гораздо больше привык к работе C++.
Мне нужно сделать что-то вроде следующего:
for item in my_dict:
if some_var == item.some_attribute:
if item.another_attribute exists:
variable = "A"
else variable = "B"
print "Duplicate item exists in my list of type: {}".format(variable)
Я сконцентрировал это на чем-то вроде этого:
if any(some_var == item.some_attribute for item in my_dict):
variable = "A" if item.another_attribute else "B"
print "Duplicate item exists in my list of type: {}".format(variable)
Однако при этом я получаю ошибку "неразрешенной ссылки" для item
. Любые идеи относительно того, как я могу написать сжатый цикл, проверку эквивалентности и проверку присутствия, как я описал выше, таким образом, что позволяет мне получать доступ и выполнять методы по item
?
Спасибо!
EDIT: Большое вам спасибо за ответ @pjhaugh, что именно то, что я искал. Прекрасно работает! Спасибо всем за ваши полезные комментарии.
Что здесь происходит, так это то, что item
не течет из области выражения генератора (это хорошо). Вы можете получить item
, получив следующее, полученное генератором, или поймав этот генератор, ничего не давая.
try:
item = next(item for item in my_dict if some_var == item.some_attribute)
variable = "A" if item.another_attribute else "B"
except StopIteration:
# there is no such item in my_dict
Как указано в моем комментарии - any(some_var == item.some_attribute for item in my_dict)
создает свою собственную локальную область. Вы не можете использовать item
за его пределами.
Тем не менее, вы можете запрограммировать свой dict так:
Создайте минимальные проверяемые полные данные примера:
class K:
def __init__(self):
self.some_attribute = None
self.another_attribute = None
def __repr__(self):
return "{} - {}".format(self.some_attribute,self.another_attribute)
def __str__(self):
return "{} - {}".format(self.some_attribute,self.another_attribute)
k1 = K()
k1.some_attribute = 99
k2 = K()
k2.some_attribute = 33
k3 = K()
k3.some_attribute = 33
k3.another_attribute = 1
my_dict = { 1: k1, 2:k2, 3:k3}
some_var = 33
Вы можете использовать цикл for так:
variable = None
for item in my_dict.items():
k,v = item
if v.some_attribute != some_var:
print "No dupe: {}".format(v)
continue
if v.some_attribute == some_var and v.another_attribute is not None:
variable = "A"
else:
variable = "B"
print "Duplicate item exists in my list of type: {}".format(variable)
print v
Выход:
No dupe: 99 - None
Duplicate item exists in my list of type: B
33 - None
Duplicate item exists in my list of type: A
33 - 1
Вы можете извлечь объекты, предоставленные итератором, в цикле for, подобном этому
for item in (i for i in my_dict if some_var == item.some_attribute):
variable = "A" if item.another_attribute is not None else "B"
print("Duplicate item exists in my list of type: {}".format(variable))
break
else: # no break encountered
... # not found
В настоящее время вы повторяете ключи словаря. Если вам нужны элементы (пары в c++ lingo), вам нужно my_dict.items()
.