【问题标题】:swapping multiple items in list交换列表中的多个项目
【发布时间】:2018-10-14 23:51:21
【问题描述】:

我想交换列表中的项目但有两个单词('go','chargers')总是交换并来举个例子:

>lst = ['hello', 'go', 'hi', 'chargers']
>lst = ['hello', 'go', 'chargers', 'hi']

我可以使用列表分配:

lst[2], lst[3] = lst[2], lst[3]

但是概括一下,它是如何工作的,例如

['hello', 'go', 'sun', 'chargers', 'good', 'go', 'can', 'chargers']
['hello', 'go', 'chargers','sun', 'good', 'go', 'chargers', 'can']

我将如何配对所有“go”“充电器”

【问题讨论】:

  • 会枚举会找到所有的值 = 'go' 和 'chargers;
  • 完成了,会枚举工作吗?还是列表分配会很好,但以更一般的方式?
  • 为什么“go”似乎从未被操纵或交换过?您是否只是交换它们是相邻的,如果两者都需要交换,则交换两者?两者都可以进行最大数量的交换吗?
  • 我只是试图将单词“chargers”交换到“go”前面的索引,从技术上讲,唯一交换的值是“chargers”和单词“go”之后的索引。因此,如果用户输入任何没有这两个单词的列表,则不会交换任何内容

标签: python list


【解决方案1】:

假设您有相同数量的“go”和“chargers”并且它们是随机放置的,您可以使用 enumerate 获取它们的索引,然后执行交换:

words = ['hello', 'go', 'sun', 'chargers', 'good', 'go', 'can', 'another word', 'chargers']

go_indices = [i for i, w in enumerate(words) if w == 'go']
charger_indices = [i for i, w in enumerate(words) if w == 'chargers']

for gi, ci in list(zip(go_indices, charger_indices)):
    words[gi + 1], words[ci] = words[ci], words[gi + 1]

print(words)
# ['hello', 'go', 'chargers', 'sun', 'good', 'go', 'chargers', 'another word', 'can']

【讨论】:

  • 好的,但理论上来说唯一需要的函数是枚举?假设我们总是得到相同数量的对?
  • @Errick-MichaelSantos 是的,您可以仅使用 enumerate 手动构建您的 ..._indices 列表。
  • @Errick-MichaelSantos 我明白你现在的意思了。您可以大大简化列表理解,只使用enumerate,然后执行您的交换。
  • 如果有两个相邻的“go”,这不起作用
【解决方案2】:

这是一个不太优雅的解决方案。首先确定充电器的位置。一旦看到去,将每个项目与充电器位置交换

lst = ['hello', 'go', 'go', 'chargers', 'good', 'sun', 'can', 'chargers']
index = 1
# loop opposite to make array, later pop them to get increasing order of sequence
allChargerIndex = [len(lst)-i-1 for i,val in enumerate(lst[::-1]) if val=="chargers"]
while index < len(lst):
    if lst[index-1] == "go":
        chargerIndex = allChargerIndex.pop()
        lst[index], lst[chargerIndex] = lst[chargerIndex], lst[index]
    index += 1
print(lst)

当然,你可以将它包含在一个函数中并尝试多种情况

def swapGoAndChargers(lst):
   index = 1
   # loop opposite to make array, later pop them to get increasing order of sequence
   allChargerIndex = [len(lst)-i-1 for i,val in enumerate(lst[::-1]) if val=="chargers"]
   while index < len(lst):
        if lst[index-1] == "go":
            chargerIndex = allChargerIndex.pop()
            lst[index], lst[chargerIndex] = lst[chargerIndex], lst[index]
        index += 1
   return lst

print(swapGoAndChargers(['hello', 'go', 'go', 'chargers', 'good', 'sun', 'can', 'chargers']))
#['hello', 'go', 'chargers', 'go', 'chargers', 'sun', 'can', 'good']
print(swapGoAndChargers(['hello', 'go', 'sun', 'chargers', 'good', 'go', 'can', 'chargers']))
#['hello', 'go', 'chargers', 'sun', 'good', 'go', 'chargers', 'can']
print(swapGoAndChargers(['go', 'hello', 'sun', 'go', 'good', 'chargers', 'can', 'chargers']))
#['go', 'chargers', 'sun', 'go', 'chargers', 'hello', 'can', 'good']

【讨论】:

    【解决方案3】:

    在截断列表上使用enumerate,然后使用多变量赋值执行交换

    for i, v in enumerate(lst[:-2]):
        if v == 'go' and lst[i + 2] == 'chargers':
            lst[i + 1], lst[i + 2] = lst[i + 2], lst[i + 1]
    
    print(lst) # => ['hello', 'go', 'chargers', 'sun', 'good', 'go', 'chargers', 'can']
    

    【讨论】:

    • 我有个问题,-2 是从哪里来的
    • @Errick-MichaelSantos 我把它放在那里以防你有一个只有chargers 的列表,lst[i-2] == 'go' 回顾两个索引来检查并确保那里的项目是go如果不是,那么我们不执行交换
    • 这有各种范围检查问题。如果列表只有一项怎么办?如果列表中的第一个单词是“充电器”(它将检查 lst[-2])等等。
    • @jarmod 你说得对,我是根据常设示例构建的,我老实说忽略了这种可能性会重做
    • @Errick-MichaelSantos 更新后应该适用于所有情况
    【解决方案4】:

    我并不是说这是特别优雅或 Pythonic。

    def go_chargers(lst):
        o = []
    
        for i in range(0, len(lst)):
            o.append(lst[i])
            if lst[i] == 'go':
                for j in range(i + 2, len(lst)):
                    if lst[j] == 'chargers':
                        lst[i+1], lst[j] = lst[j], lst[i+1]
                        break
        return o
    
    print(go_chargers(['go', 'sun', 'chargers', 'good', 'go', 'can', 'chargers']))
    # ['go', 'chargers', 'sun', 'good', 'go', 'chargers', 'can']
    
    print(go_chargers( ["Rock", "go", "Stars", "go", "Paper", "chargers", "Scissors", "chargers"]))
    # ['Rock', 'go', 'chargers', 'go', 'chargers', 'Stars', 'Scissors', 'Paper']
    

    【讨论】:

    • 我用我的其他测试用例之一尝试过它,但它似乎没有采用第二对。[“Rock”,“go”,“Stars”,“go”,“Paper”, “充电器”、“剪刀”、“充电器”]
    • 测试用例是什么?
    • [“Rock”、“go”、“Stars”、“go”、“Paper”、“chargers”、“Scissors”、“chargers”]
    • 啊,在没有完整规范的情况下开始工作的危险。这与前面用一个单词分隔“go”和“chargers”的示例不匹配。您在这里的预期输出是什么?我猜 [“Rock”、“go”、“chargers”、“go”、“chargers”、“Stars”、“Scissors”、“Paper”]。
    • @Errick-MichaelSantos 我昨晚更新了代码以包含您更新的请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 2011-12-15
    • 1970-01-01
    • 2021-12-27
    • 2013-11-09
    • 2016-01-13
    • 2011-11-19
    相关资源
    最近更新 更多