Удаление значений из списка в Python - PullRequest
0 голосов
/ 28 июля 2010

У меня большой файл имен и значений в одной строке, разделенных пробелом:

name1 name2 name3....

За длинным списком имен следует список значений, соответствующих именам. Значения могут быть 0-4 или na. Я хочу объединить файл данных и удалить все имена и значения, когда значение равно na.

Например, последняя строка имени в этом файле выглядит так:

namenexttolast nameonemore namethelast 0 na 2

Я бы хотел следующий вывод:

namenexttolast namethelast 0 2

Как бы я сделал это с помощью Python?

Ответы [ 6 ]

5 голосов
/ 28 июля 2010

Допустим, вы читаете имена в один список, а затем значения в другой. Если у вас есть список names и values, вы можете сделать что-то вроде:

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

result теперь представляет собой список всех имен, значение которых не равно "na".

4 голосов
/ 28 июля 2010
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 будет создан и немедленно отброшен.

1 голос
/ 29 июля 2010

Я согласен с Джастином, что использование zip - хорошая идея.Проблема в том, как поместить данные в два разных списка.Вот предложение, которое должно работать нормально.

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
1 голос
/ 28 июля 2010

или, скажем, у вас есть строка, которую вы прочитали из файла.Давайте назовем эту строку как «s»

words = filter(lambda x: x!="na", s.split())

должен дать вам все строки, кроме «na»

edit: приведенный выше код явно не делает то, что вы хотите, чтобы он делал.

приведенный ниже должен работать, хотя

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])])
0 голосов
/ 29 июля 2010

Вот решение, в котором используются только итераторы и один элемент буфера, без вызовов len и создания других промежуточных списков. (В Python 3 просто используйте map и zip, нет необходимости импортировать imap и izip из itertools.)

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
0 голосов
/ 29 июля 2010
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

Если вы предпочитаете группировать значения, вы можете создать список кортежей (закомментированная строка)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...