检查特定元素列表的更好方法 - python

Better way to check a list for specific elements - python

我正在使用 try/except 块来替代具有一堆 andif/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 的优势:

  1. 更少的代码行,如果你喜欢的话
  2. 更具可读性 - 任何未来 reader 都会立即明白你的意思

相对于 try/except 的缺点:

  1. 更慢(虽然完全可以忽略不计)因为 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'}