检查特定元素列表的更好方法 - python
Better way to check a list for specific elements - python
我正在使用 try/except
块来替代具有一堆 and
的 if/elif
。我正在查看一个列表并替换一些元素,如果它有 x 和 x 和 x 等。在我的项目中,我必须检查超过 6 个吸引我使用 try/except
和 [=16= 的东西] 如果该元素不存在,将引发错误。
类比如下:
colors = ['red', 'blue', 'yellow', 'orange']
try:
red_index = colors.index('red')
blue_index = colors.index('blue')
colors[red_index] = 'pink'
colors[blue_index] = 'light blue'
except ValueError:
pass
try:
yellow_index = colors.index('yellow')
purple_index = colors.index('purple')
colors[yellow_index] = 'amarillo'
colors[purple_index] = 'lavender'
except ValueError:
pass
因此,如果 colors
数组不包含 'purple'
以及 'yellow'
,我不想更改数组。
我对这种方法有点警惕,因为它似乎是在滥用 try/except
。但它比替代方案短得多,因为无论如何我都必须抓住元素的 index
,所以我想知道这是否存在明显的问题,或者这是否足够疯狂以至于其他开发人员会讨厌我它。
更新答案
您可能希望使用 map() 构建函数,如下所示:
def replace(sequence, replaceDict):
for seekVal in replaceDict.keys():
if seekVal not in sequence:
return sequence #Not modified, as seek not found.
replaceFunc = lambda item: replaceVal if item==seekVal else item
for seekVal in replaceDict:
replaceVal = replaceDict[seekVal]
sequence = map(replaceFunc, sequence)
return sequence
然后 运行:
colors = replace(colors, {'red' : 'pink', 'blue' : 'light blue'})
您的代码很接近,但有一些有用的内置函数可以提供帮助:
colors = ['red', 'blue', 'yellow', 'orange']
if ('red' in colors and 'blue' in colors):
red_index = colors.index('red')
blue_index = colors.index('blue')
colors[red_index] = 'pink'
colors[blue_index] = 'light blue'
if ('yellow' in colors and 'purple' in colors):
yellow_index = colors.index('yellow')
purple_index = colors.index('purple')
colors[yellow_index] = 'amarillo'
colors[purple_index] = 'lavender'
这会创建逻辑门(两种颜色都必须存在),因此它只会在您需要时执行。
这是一个非常小的变化,但我认为它会以更好的方式处理您的错误情况。
实际上,您可以使用 dict
和这样的列表理解以更简单、更短的方式进行:
colors = ['red', 'blue', 'yellow', 'orange']
# First define you replaces
replaces = {
'red': 'ping',
'blue': 'light blue',
'yellow': 'amarillo',
'purple': 'lavender'
}
# Then define the replacing function
def replace(key, replaces):
return replaces.get(key) or key
# And then replace all the intended element
colors = [replace(el, replaces) for el in colors]
所以这会做什么,对于每个元素,它会在字典中查找它,如果它在字典中(即打算被替换),那么它将 return 适当的替换,否则,它将return原始值。
那么介绍一下你的条件,你可以这样说:
if 'purple' in colors and 'red' in colors:
colors = [replace(el, {
'yellow': 'amarillo',
'purple': 'lavender'
}) for el in colors]
...
其他情况也一样。
这并不疯狂; try/except 非常 pythonic - 请参阅 this question 了解更多讨论。
另一种方法是:
if 'red' in colours and 'blue' in colours:
colour[colours.index('red')] = 'pink'
# etc
相对于 try/except 的优势:
- 更少的代码行,如果你喜欢的话
- 更具可读性 - 任何未来 reader 都会立即明白你的意思
相对于 try/except 的缺点:
- 更慢(虽然完全可以忽略不计)因为
contains
将自己搜索元素。
除非你正在做一些要求它非常节省时间的事情,否则我更喜欢可读性。但是,如果您有其他原因,try/except 并非不可原谅。
您可以使用 set
. We'll use issuperset
, difference_update
, and update
,分别缩写为 >=
、-=
和 |=
:
colors = {'red', 'blue', 'yellow', 'orange'}
if colors >= {'red', 'blue'}:
colors -= {'red', 'blue'}
colors |= {'pink', 'light blue'}
elif colors >= {'yellow', 'purple'}:
colors -= {'yellow', 'purple'}
colors |= {'amarillo', 'lavender'}
我正在使用 try/except
块来替代具有一堆 and
的 if/elif
。我正在查看一个列表并替换一些元素,如果它有 x 和 x 和 x 等。在我的项目中,我必须检查超过 6 个吸引我使用 try/except
和 [=16= 的东西] 如果该元素不存在,将引发错误。
类比如下:
colors = ['red', 'blue', 'yellow', 'orange']
try:
red_index = colors.index('red')
blue_index = colors.index('blue')
colors[red_index] = 'pink'
colors[blue_index] = 'light blue'
except ValueError:
pass
try:
yellow_index = colors.index('yellow')
purple_index = colors.index('purple')
colors[yellow_index] = 'amarillo'
colors[purple_index] = 'lavender'
except ValueError:
pass
因此,如果 colors
数组不包含 'purple'
以及 'yellow'
,我不想更改数组。
我对这种方法有点警惕,因为它似乎是在滥用 try/except
。但它比替代方案短得多,因为无论如何我都必须抓住元素的 index
,所以我想知道这是否存在明显的问题,或者这是否足够疯狂以至于其他开发人员会讨厌我它。
更新答案
您可能希望使用 map() 构建函数,如下所示:
def replace(sequence, replaceDict):
for seekVal in replaceDict.keys():
if seekVal not in sequence:
return sequence #Not modified, as seek not found.
replaceFunc = lambda item: replaceVal if item==seekVal else item
for seekVal in replaceDict:
replaceVal = replaceDict[seekVal]
sequence = map(replaceFunc, sequence)
return sequence
然后 运行:
colors = replace(colors, {'red' : 'pink', 'blue' : 'light blue'})
您的代码很接近,但有一些有用的内置函数可以提供帮助:
colors = ['red', 'blue', 'yellow', 'orange']
if ('red' in colors and 'blue' in colors):
red_index = colors.index('red')
blue_index = colors.index('blue')
colors[red_index] = 'pink'
colors[blue_index] = 'light blue'
if ('yellow' in colors and 'purple' in colors):
yellow_index = colors.index('yellow')
purple_index = colors.index('purple')
colors[yellow_index] = 'amarillo'
colors[purple_index] = 'lavender'
这会创建逻辑门(两种颜色都必须存在),因此它只会在您需要时执行。
这是一个非常小的变化,但我认为它会以更好的方式处理您的错误情况。
实际上,您可以使用 dict
和这样的列表理解以更简单、更短的方式进行:
colors = ['red', 'blue', 'yellow', 'orange']
# First define you replaces
replaces = {
'red': 'ping',
'blue': 'light blue',
'yellow': 'amarillo',
'purple': 'lavender'
}
# Then define the replacing function
def replace(key, replaces):
return replaces.get(key) or key
# And then replace all the intended element
colors = [replace(el, replaces) for el in colors]
所以这会做什么,对于每个元素,它会在字典中查找它,如果它在字典中(即打算被替换),那么它将 return 适当的替换,否则,它将return原始值。
那么介绍一下你的条件,你可以这样说:
if 'purple' in colors and 'red' in colors:
colors = [replace(el, {
'yellow': 'amarillo',
'purple': 'lavender'
}) for el in colors]
...
其他情况也一样。
这并不疯狂; try/except 非常 pythonic - 请参阅 this question 了解更多讨论。
另一种方法是:
if 'red' in colours and 'blue' in colours:
colour[colours.index('red')] = 'pink'
# etc
相对于 try/except 的优势:
- 更少的代码行,如果你喜欢的话
- 更具可读性 - 任何未来 reader 都会立即明白你的意思
相对于 try/except 的缺点:
- 更慢(虽然完全可以忽略不计)因为
contains
将自己搜索元素。
除非你正在做一些要求它非常节省时间的事情,否则我更喜欢可读性。但是,如果您有其他原因,try/except 并非不可原谅。
您可以使用 set
. We'll use issuperset
, difference_update
, and update
,分别缩写为 >=
、-=
和 |=
:
colors = {'red', 'blue', 'yellow', 'orange'}
if colors >= {'red', 'blue'}:
colors -= {'red', 'blue'}
colors |= {'pink', 'light blue'}
elif colors >= {'yellow', 'purple'}:
colors -= {'yellow', 'purple'}
colors |= {'amarillo', 'lavender'}