2010-07-28 3 views
0

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

name1 name2 name3....

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

Например, последняя строка имени в этом файле следующим образом:

namenexttolast nameonemore namethelast 0 na 2

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

namenexttolast namethelast 0 2

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

+0

Я предполагаю, что вы не имеете никакого контроля над форматом данные приходят, но только в том случае, если вы делаете, это сделает ваш код более элегантным, если вы имели имена и значения на отдельных строках. – katrielalex

+3

Редактирование по этому вопросу является эпическим. Престижность Уэйн Вернер за практически божественное редактирование. –

+0

Зачем, спасибо! Я просто не могу терпеть плохое общение, и если я смогу хотя бы разобраться в том, что они спрашивают, я пойду дальше и помогу. В конце концов, никто действительно не пользуется плохо сформулированным/отформатированным вопросом (или ответом), и, по крайней мере, кто-то может принести пользу, если вопрос немного опрятен. Просто сделаю свою часть для сообщества SO :) –

ответ

1

Я согласен с Джастином, а не с помощью 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 
+0

Я считаю, что вам нужно будет написать пробел между написанием ваших двух списков или ваша фамилия и ваше первое значение будут работать вместе. –

+0

@Jesse: Правильно, спасибо. Я видел ваш ответ перед отправкой моего. Это очень похоже, но я решил опубликовать его. Я не хотел тратить несколько минут, потраченных на это. :) – luc

5

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

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

result теперь список всех имен, значение которых не «на».

+1

OP запросил строку в том же формате, что и вход, например. 'n1 n2 n3 v1 v2 v3', где нет значений' na'. Вы указываете имена этих пользователей и отбрасываете значения. –

+0

Я считаю, что это изменение произошло после моего ответа. К настоящему времени в других ответах описано, как это сделать, не отбрасывая значения. –

1

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

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

должны дать вам все строки для «па»

редактировать, за исключением: код выше, очевидно, не делать то, что вы хотите, чтобы это сделать.

ниже один должен работать, хотя

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

Хотя довольно трудно читать, мне нравится семантика итерации в списке. +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) 

Update

незначительное улучшение после предложения от Павла. Я уверен, что понимание списка довольно неряшливо, так как оно использует тот факт, что list.append возвращает None, поэтому будут вычислены выражения append и будет выстроен список значений None и сразу же выброшен.

+0

Сохранение имен и значений в dict, а затем их возврат с использованием iteritems не сохранит порядок имен. (Неясно, заботится ли OP о порядке или нет.) В этом случае 'names_and_values' уже является списком пар имя-значение, зачем создавать dict только для того, чтобы извлечь из него iteritems? Просто перебирайте «names_and_values». – PaulMcG

+0

@Paul В ответ на ваши отзывы я сделал пару изменений, которые вы можете или не можете оценить. –

+0

Yeeps! Я это вдохновлял? О, пожалуйста, не привыкните использовать список comps как for-loop-one-liners. Лучше изучить 'zip (* seq_of_seqs)' для выполнения транспонирования последовательности последовательностей. Но да, я должен признать, что это было умно. Просто НЕ КОГДА-ЛИБО ЭТО СНОВА! :) – PaulMcG

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 

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

0

Вот решение, которое использует только итераторы плюс один элемент буфера, без звонков в 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 

 Смежные вопросы

  • Нет связанных вопросов^_^