我知道有100种方法可以解决这个问题,我要求社区了解最恐怖的方法似乎是什么。
假设我有一个采用以下格式的词典列表:
colours = [{"color": "green", "owner": "Mark"},
{"color": "blue", "owner": "Luke"},
{"color": "red", "owner": "John"}]
忽略列表应该是字典词典这一显而易见的事实,我想从列表中检索单个字典,给出字典中color
键的用户输入,但是使用默认值如果颜色不匹配(在本例中假设为“绿色”)。
因此我正在寻求一个功能:
def get_with_default(colour, colours, default):
鉴于颜色列表会返回:
>>> get_with_default("blue", colours, "green") # Valid dictionary
{"color": "blue", "owner": "Luke"}
>>> get_with_default("black", colours, "green") # Colour doesn't exist
{"color": "green", "owner": "Mark"}
更新(感谢Martijn),默认值将是硬编码并且已知在列表中,然而该字典中的其他键/值对是未知/动态(所以我知道'绿色'是字典中的一个关键字,但我不知道在这个简化案例中谁拥有'绿色
答案 0 :(得分:4)
next()
是实现这一目标的最具蟒蛇功能:
def get_with_default(colour, colours, default):
search = (d for d in colours if d['color'] in (colour, default))
match_or_default = next(search)
if match_or_default['color'] != default or default == colour:
return match_or_default
return next(search, match_or_default)
next()
遍历第一个参数,直到产生结果,然后返回。如果第一个参数用尽,则会引发StopIteration
,除非给出第二个参数,否则为默认值,在这种情况下返回该值而不是引发异常。
通过为其提供体现搜索的生成器表达式,您可以有效地扫描colours
列表中的第一个匹配项。如果结果是默认值,那么我们会继续扫描,直到找到其他匹配,或者到达列表的末尾。
演示:
>>> get_with_default("blue", colours, "green")
{'color': 'blue', 'owner': 'Luke'}
>>> get_with_default("black", colours, "green")
{'color': 'green', 'owner': 'Mark'}
上述方法非常有效,因为它只需要扫描输入列表一次,并且一旦找到匹配就立即停止扫描。
请注意,如果默认值不存在,此函数将引发StopIteration
:
>>> get_with_default("black", colours, "purple")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in get_with_default
StopIteration
在这种情况下,您可以通过向第一个None
调用提供默认返回值来返回next()
:
match_or_default = next(search, None)
答案 1 :(得分:2)
不是最好的,但又好又可读:
def get_with_default(colour, L, default=''):
temp = None
for d in L:
if d['color'] == colour:
return d
elif d['color'] == default:
temp = d
return temp
测试时:
>>> get_with_default('blue', colours, 'green')
{'color': 'blue', 'owner': 'Luke'}
>>> get_with_default('black', colours, 'green')
{'color': 'green', 'owner': 'Mark'}
答案 2 :(得分:0)
您还可以使用列表理解来实现此目的。
def get_with_defaults(color,colours,default='green'):
res = [col for col in colours if col['color']==color]
if not res:
return [col for col in colours if col['color']==default]
return res
get_with_defaults('blue',colours)
[{'color': 'blue', 'owner': 'Luke'}]
>>> get_with_defaults('black',colours)
[{'color': 'green', 'owner': 'Mark'}]
字典输出。
def get_with_defaults(color,colours,default='green'):
res = [col for col in colours if col['color']==color]
if not res:
return [col for col in colours if col['color']==default][0]
return res[0]
get_with_defaults('blue',colours)
{'color': 'blue', 'owner': 'Luke'}
>>> get_with_defaults('black',colours)
{'color': 'green', 'owner': 'Mark'}