从python中的列表中删除值

时间:2010-07-28 19:07:16

标签: python text-parsing

我有一个由空格分隔的单行上的大型名称和值文件:

name1 name2 name3....

在长名单后面是与名称对应的值列表。值可以是0-4或na。我想要做的是合并数据文件,并在值为na时删除所有名称和值。

例如,此文件中的最后一行名称是这样的:

namenexttolast nameonemore namethelast 0 na 2

我想要以下输出:

namenexttolast namethelast 0 2

我如何使用Python做到这一点?

6 个答案:

答案 0 :(得分:5)

假设您将名称读入一个列表,然后将值读入另一个列表。获得namesvalues列表后,您可以执行以下操作:

result = [n for n, v in zip(names, values) if v != 'na']

result现在是所有名称不是“na”的名称的列表。

答案 1 :(得分:4)

s = "name1 name2 name3 v1 na v2"
s = s.split(' ')
names = s[:len(s)/2]
values = s[len(s)/2:]

names_and_values = zip(names, values)
names, values = [], []
[(names.append(n) or values.append(v)) for n, v in names_and_values if v != "na"]
names.extend(values)

print ' '.join(names)

<强>更新

保罗的建议后略有改善。我确信列表理解是相当单一的,因为它利用list.append返回None的事实,因此将评估append个表达式和None值的列表将被建造并立即扔掉。

答案 2 :(得分:1)

或者说你有一个从文件中读取的字符串。我们将此字符串称为“s”

words = filter(lambda x: x!="na", s.split())
除了“na”

之外,

应该给你所有的字符串

编辑:上面的代码显然没有按照您的意愿执行。

下面的那个应该可以工作

d = s.split()
keys = d[:len(d)/2]
vals = d[len(d)/2:]
w = " ".join(map(lambda (k,v): (k + " " + v) if v!="na" else "", zip(keys, vals)))
print " ".join([" ".join(w.split()[::2]), " ".join(w.split()[1::2])])

答案 3 :(得分:1)

我同意贾斯汀而不是使用拉链是一个好主意。问题是如何将数据放入两个不同的列表中。这是一个应该可行的提案。

reader = open('input.txt')
writer = open('output.txt', 'w')
names, nums = [], []
row = reader.read().split(' ')
x = len(row)/2
for (a, b) in [(n, v) for n, v in zip(row[:x], row[x:]) if v!='na']:
    names.append(a)
    nums.append(b)
writer.write(' '.join(names))
writer.write(' ')
writer.write(' '.join(nums))
#writer.write(' '.join(names+nums)) is nicer but cause list to be concat

答案 4 :(得分:0)

strlist = 'namenexttolast nameonemore namethelast 0 na 2'.split()
vals = ('0', '1', '2', '3', '4', 'na')
key_list = [s for s in strlist if s not in vals]
val_list = [s for s in strlist if s in vals]

#print [(key_list[i],v) for i, v in enumerate(val_list) if v != 'na']
filtered_keys = [key_list[i] for i, v in enumerate(val_list) if v != 'na']
filtered_vals = [v for v in val_list if v != 'na']

print filtered_keys + filtered_vals

如果您更愿意对val进行分组,则可以创建一个元组列表(注释掉行)

答案 5 :(得分:0)

这是一个只使用迭代器加上一个缓冲区元素的解决方案,没有调用len而没有创建其他中间列表。 (在Python 3中,只需使用mapzip,无需从itertools导入imapizip。)

from itertools import izip, imap, ifilter

def iterStartingAt(cond, seq):
    it1,it2 = iter(seq),iter(seq)
    while not cond(it1.next()):
        it2.next()
    for item in it2:
        yield item

dataline = "namenexttolast nameonemore namethelast 0 na 2"
datalinelist = dataline.split()

valueset = set("0 1 2 3 4 na".split())

print " ".join(imap(" ".join, 
                    izip(*ifilter(lambda (n,v): v != 'na', 
                                  izip(iter(datalinelist), 
                                       iterStartingAt(lambda s: s in valueset, 
                                                      datalinelist))))))

打印:

namenexttolast namethelast 0 2