Python 替换列表中的N个特定条目

Python 替换列表中的N个特定条目,python,Python,我有以下字符串列表: ['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44',

我有以下字符串列表:

['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']
这是从一个非常混乱的
.txt
文件中解析出来的。每组“空白”条目对应一个零,但我需要将这些零记录为999s(我基本上需要将每组4个连续的
'
替换为
'999'
)。做这件事的最有可能的方式是什么

>>> from itertools import groupby
... 
... 
... def group_blanks_by_n(lst, n=4):
...     result = []
...     for k, g in groupby(lst):
...         if k == '':
...             quo, rem = divmod(sum(1 for _ in g), n)
...             result.extend(['999'] * quo)
...             result.extend([''] * rem)
...         else:
...             result.extend(g)
...     return result
... 
>>> test = ['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']
>>> group_blanks_by_n(test, n=4)
['17', ' 5', ' 6', ' 0', ' 0', '999', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '999', '999', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '999', '999', '999', '999', '999', ' 28.68', '999', '999', '999', '999', '999', '999', '999', '999', '', '1.40']

编辑:

添加了
n
参数以说明不同的值(不必默认为
4
,仅选择与问题描述匹配)。

使用(在Python 3中,也称为):

代码: 结果:
这里有一个小函数,可以满足您的需要

a = ['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']

def f(list):
    r = []
    c = 0
    for item in list:
        if item == '':
            c += 1
            if c == 4:
                r.append('999')
                c = 0
        else:
            c = 0
            r.append(item)
    return r

print f(a)

['17', ' 5', ' 6', ' 0', ' 0', '999', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '999', '999', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '999', '999', '999', '999', '999', ' 28.68', '999', '999', '999', '999', '999', '999', '999', '999', '1.40']

另一种方法是使用join()将列表转换为字符串,然后用999替换空格,然后使用split()再次转换为列表


我想这是最像蟒蛇的方式吧

from itertools import groupby

L = ['17', ' 5', '6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']

def your_function(L):
    grouped_L = [(k, len(list(g))) for k,g in groupby(L)]
    final_list = [item 
    for x, y in grouped_L 
    for item in repeat(x if y < 4 else '999', y if y < 4 else y // 4)]
    return final_list

print(your_function(L))
从itertools导入groupby
L=['17', ' 5', '6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']
定义您的_函数(L):
grouped_L=[(k,len(list(g)))表示groupby(L)中的k,g]
最终清单=[项目]
对于x,y,在分组的
对于重复项(如果y<4,则为x,否则为'999',如果y<4,则为y//4)]
返回最终用户列表
打印(您的_函数(L))
使用groupbyitertools中的repeat,这将生成如下元组列表

[(k,len(list(g)))对于groupby(L)中的k,g]

[('17',1),('5',1),('6',1),('0',2),('',4),…等等]

其中输出是一个元组=>(项,它的连续出现次数)

然后再次使用列表理解

注:(x,y)=>(项目,其连续出现的次数)

final_list=[项目
对于x,y,在分组的
对于重复项(如果y<4,则为x,否则为'999',如果y<4,则为y//4)]

显示预期结果如果其中一个答案解决了您的问题,请接受它。遗憾的是,如果列表以4个尾随
'
开头或结尾,则该列表不起作用。做得很好,与我的列表非常相似,它使用生成器表达式而不是join来处理4个空字符串的前导/尾随集。1+@alec_djin这似乎不会返回e正确答案。如果我正确理解了问题,则
c
变量的结尾应该是
'999',''1.40']
,而不是
,'9991.40']
。也许TimGeb在投票前就错过了。@ PythonMania,没错,我尽快检查。@ DeliriousLettuce是一个有线拷贝/粘贴错误,输出是正确的,但是空白字符已经走了(因为拆分),但是“999”和“1.40”是正确分开的,不确定如果它想要的话。非常感谢!我忘了提到在我的例子中最好的解决方案是一个函数,因为我需要对不同的“N”值(在这个例子中,它是4)这样做。干杯:)@PythonMania我调整了代码,以便将不同的
n
值传递给它。这回答了你的问题吗?这个版本完全忽略了从结尾开始的第二个空字符串<代码>'999','1.40']应该是
'999','1.40']
。您的解决方案似乎根本无法正常工作。问题是用“999”替换每组4个连续的“999”。您的解决方案将任意数量的连续“”替换为单个“999”。您错过了结尾第二个空字符串,并且在
L[4]
处销毁了第二个零。您没有注意到这一点。当我发布答案时,他太困了。在其他SO用户的帮助下,现在进行了更正!您的解决方案没有运行,因为您没有导入
itertools。请重复
。即使添加了该导入,您的解决方案也不正确。在最后一次连续运行的空字符串中有33个
'
,并且
divmod(33,4)==(8,1)
。因此,
final_list
中的第二个最后一项应该是
'
(因为它不是一组4个),但您的解决方案完全忽略了这一点。作为旁注,
final_list
list comprehension中的行应该缩进。@delerious不,它们不需要缩进。这也是表示列表理解的正确方法。即使在我指出错误之后,您也没有修复您的解决方案。此外,您关于缩进的陈述没有任何来源的支持。
a = ['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']

def f(list):
    r = []
    c = 0
    for item in list:
        if item == '':
            c += 1
            if c == 4:
                r.append('999')
                c = 0
        else:
            c = 0
            r.append(item)
    return r

print f(a)

['17', ' 5', ' 6', ' 0', ' 0', '999', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '999', '999', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '999', '999', '999', '999', '999', ' 28.68', '999', '999', '999', '999', '999', '999', '999', '999', '1.40']
a = ['17', ' 5', ' 6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']

b = '*'.join(a).replace(4*'*',' 999 ').replace('*','')
c = b.split()
print c

['17', '5', '6', '0', '0', '999', '10.11', '10.57', '18.34', '16.41', '13.23', '11.55', '11.56', '999', '999', '12.77', '11.99', '21.88', '22.46', '26.82', '25.71', '27.43', '27.73', '29.44', '999', '999', '999', '999', '999', '28.68', '999', '999', '999', '999', '999', '999', '999', '999', '1.40']
from itertools import groupby

L = ['17', ' 5', '6', ' 0', ' 0', '', '', '', '', ' 10.11', ' 10.57', ' 18.34', ' 16.41', ' 13.23', ' 11.55', ' 11.56', '', '', '', '', '', '', '', '', ' 12.77', ' 11.99', ' 21.88', ' 22.46', ' 26.82', ' 25.71', ' 27.43', ' 27.73', ' 29.44', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ' 28.68', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '1.40']

def your_function(L):
    grouped_L = [(k, len(list(g))) for k,g in groupby(L)]
    final_list = [item 
    for x, y in grouped_L 
    for item in repeat(x if y < 4 else '999', y if y < 4 else y // 4)]
    return final_list

print(your_function(L))
final_list = [item 
    for x, y in grouped_L 
    for item in repeat(x if y < 4 else '999', y if y < 4 else y // 4)]