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))
使用groupby和itertools中的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)]