【问题标题】:merging strings from a list in python合并python列表中的字符串
【发布时间】:2021-04-07 23:01:32
【问题描述】:

我试图在 python 上定义一个函数来合并字符串列表中给定索引范围内的字符串。这是我的代码:

def merge_some(L,i,j):
    result=L[:]
    merging=''
    for k in range(i,j+1):
        merging +=L[k]
    result[i:j+1]=merging
    return result

trial= ['a','b','c','d','e','f']
print(merge_some(trial, 1,3))  #index 3 included

输出应该是:

['a','bcd','d','e','f']

代码应该可以正常工作,但是如果我运行它,我只会返回原始列表,这对我来说很奇怪。虽然我知道有很多方法可以计算这样的函数(例如,使用 .join() 方法而不是循环),但我想问一下是否有人知道这种奇怪行为的原因。 任何想法将不胜感激。非常感谢!

【问题讨论】:

  • 也许可以使用print() 来查看变量中的内容。
  • 我不知道为什么您的切片分配不起作用,但这样做:result=result[:i]+[merging]+result[j+1:](编辑:这也适用:result[i:j+1]=[merging]
  • 实际原因是merging是一个字符串,在切片赋值的时候变成了一个字母列表!所以“bcd”看起来像这样:['b','c','d'] 所以你最终替换了已经存在的东西!!!

标签: python list function merge


【解决方案1】:

你可以这样做:

def merge_some(L,i,j):
    result=L[:]
    result[i:j+1]=[''.join(L[i:j+1])]
    return result


>>> merge_some(['a','b','c','d','e','f'], 1,3)
['a', 'bcd', 'e', 'f']

有两点需要注意:

  1. result[i:j+1] 部分是slice assignment,它将切片的内容替换为 RH 侧的内容(即使大小与切片不同);
  2. ''.join(L[i:j+1]) 从这些元素创建单个字符串;
  3. [''.join(L[i:j+1])] 周围的 [...] 使该字符串充当切片分配的单个元素。

【讨论】:

    【解决方案2】:

    str.join() 应该为你解决这个问题:

    def merge_some(l, from_i,to):
        return l[: from_i]+[''.join(l[from_i:to+1])]+l[to+1:]
    
    trial= ['a','b','c','d','e','f']
    print(merge_some(trial, 1,3))
    >>> ['a','bcd','e','f']
    

    注意:您在建议预期结果时错误地计算了索引(因此您添加了 j+1,在我看来这似乎不是很直观),但如果您的意思是您想要很多项目而不是“要”就这样做:

    def merge_some(l, from_i,many):
        return l[: from_i]+[''.join(l[from_i: from_i + many -1])]+l[from_i +many-1:]
    trial= ['a','b','c','d','e','f']
    print(merge_some(trial, 1,3))
    >>> ['a','bcd','e','f']
    

    【讨论】:

    • from 是python中的保留关键字。不要使用 ist 作为变量名!
    【解决方案3】:

    首先,非常感谢大家的帮助。 虽然我已经知道 .join() 方法,正如我的问题中提到的那样,但我只是发现了我的代码中缺少的内容以及这种奇怪行为的原因:

    def merge_some(L,i,j):
        try:
            result=L[:]
            merging=''
            for k in range(i,j+1):
                merging +=L[k]
            result[i:j+1]=[merging]
            return result
        except:
            return []
    
    trial= ['a','b','c','d','e','f']
    print(merge_some(trial, 1,3))   #The index=3 is also merged in the script
    

    因此缺少的是[merging],即必须将切片分配声明为可迭代。

    【讨论】:

    • 实际原因是merging是一个字符串,在切片赋值的时候变成了一个字母列表!所以“bcd”看起来像这样: ['b','c','d'] 所以你最终替换了已经存在的东西!!!现在说得通了!
    【解决方案4】:

    您使用参数j 的方式违背了惯例。在调用merge_some 时,不向j 添加1 而是将1 到4 作为参数传递会更直观。

    您在问题中得到的结果是由于第 6 行。

    您的问题和答案中的代码的另一个问题是,当您传递一个空列表时,您会超出范围,因此您必须为此添加一个检查。

    我建议使用以下解决方案,因为它也适用于空列表:

    def merge_some(values, start, end):
        return list(filter(None, values[:start] + [''.join(values[start:end])] + values[end:]))
    
    letters = ['a', 'b', 'c', 'd', 'e', 'f']
    print(merge_some(letters, 1, 4))
    

    请注意,我将 1 到 4 作为参数传递。

    结果:

    >>> ['a', 'bcd', 'e', 'f']
    

    【讨论】:

    • 谢谢,我编辑了,现在也适用于空列表。虽然我不明白你关于索引的观点,但如果有人希望函数中的最后一个索引也包括在内,那么我找不到任何错误。
    • 您可以做任何您喜欢的事情,但关键是通常最好与常规做法保持一致。当有人使用该功能时,他可能会感到困惑。然后,您必须为函数编写注释来解释不同的行为,但许多人往往不阅读 cmets。
    猜你喜欢
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 2017-08-29
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多