2014-02-10 2 views
10

Я не уверен, могу ли я проясниться, но попробую.pop/удалить элементы из кортежа python

У меня есть кортеж в python, который я просматриваю следующим образом (см. Код ниже). Пройдя через него, я поддерживаю счетчик (назовем его «n») и «pop», которые соответствуют определенному условию.

Теперь, конечно, после того, как я вытащил первый элемент, нумерация все идет не так, как я могу сделать то, что хочу сделать более элегантно, одновременно удаляя только некоторые элементы кортежа на лету?

for x in tupleX: 
    n=0 
    if (condition): 
    tupleX.pop(n) 
    n=n+1 
+5

'tuple's неизменны, и не имеют' pop' метод. Вы действительно говорите о «списке»? – DSM

ответ

2

ОК Я выяснил грубый способ сделать это.

хранить «N» значение в поле для цикла, когда условие выполнено в виде списка (назовем его delList), то сделайте следующее:

for ii in sorted(delList, reverse=True): 
    tupleX.pop(ii) 

Любые другие предложения приветствуются тоже.

2

Возможно, вы хотите словари?

d = dict((i,value) for i,value in enumerate(tple)) 
while d: 
    bla bla bla 
    del b[x] 
+0

нет Мне нужно работать с кортежем, как это было дано мне внешней функцией, которую я не могу редактировать - старый иерархический код со слишком большим количеством зависимостей. –

+0

ok, см. Редактирование ... –

+0

спасибо, я попробую это - более элегантный, чем мой метод. –

28

Как DSM упоминает, tuple «s неизменны, но даже для списков, более элегантное решение заключается в использовании filter:

tupleX = filter(str.isdigit, tupleX) 

или, если condition не является функцией, использовать понимание:

tupleX = [x for x in tupleX if x > 5] 

, если вам действительно нужно Tuplex быть кортеж, использовать выражение генератора и передать в tuple:

tupleX = tuple(x for x in tupleX if condition) 
+1

Для ссылки других, выражение генератора является оптимальным с точки зрения скорости. –

+0

@Alecg_O: можете ли вы предоставить ориентиры для этого требования? Фактически, в случае, когда 'condition' является (непримененной) C-функцией (как в приведенном примере),' filter' обычно быстрее; генераторные выражения должны выполнять некоторый байт-код python, но не обязаны создавать кадр вызова (также как в моем примере для понимания списка). – SingleNegationElimination

+0

Согласно [docs] (https://docs.python.org/3/library/functions.html#filter), фильтры и генераторные решения функционально идентичны - оба возвращают итерируемый исходный фильтр по условию и по этому определению оба являются постоянным временем. Однако, предполагая, что OP требует кортежа для вывода, разница приходит в обратном порядке. Для доказательства: возьмите tuple() с генератора, и они оба вернутся мгновенно, но tuple() фильтр, и это займет больше времени пропорционально размеру tupleX. –

0

Существует простое, но практичное решение.

Как сказано в DSM, кортежи неизменяемы, но мы знаем, что списки являются изменяемыми. Итак, если вы измените кортеж на список, он будет изменен. Затем вы можете удалить элементы по условию, а затем снова изменить тип на кортеж. Это оно.

Пожалуйста, смотрите ниже коды:

tuplex = list(tuplex) 
for x in tuplex: 
    if (condition): 
    tuplex.pop(tuplex.index(x)) 
tuplex = tuple(tuplex) 
print(tuplex) 

Например, следующая процедура удалит все четные числа из данного набора.

tuplex = (1, 2, 3, 4, 5, 6, 7, 8, 9) 
tuplex = list(tuplex) 
for x in tuplex: 
    if (x % 2 == 0): 
    tuplex.pop(tuplex.index(x)) 
tuplex = tuple(tuplex) 
print(tuplex) 

Если вы проверите тип последнего дуплекса, вы обнаружите, что это кортеж.

И, наконец, если вы хотите определить счетчик индексов, как вы это делали (т. Е. N), вы должны инициализировать его перед циклом, а не в цикле.

0

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

Демо:

my_tuple = (10, 20, 30, 40, 50) 

# converting the tuple to the list 
my_list = list(my_tuple) 
print my_list # output: [10, 20, 30, 40, 50] 

# Here i wanna delete second element "20" 
my_list.pop(1) # output: [10, 30, 40, 50] 
# As you aware that pop(1) indicates second position 

# Here i wanna remove the element "50" 
my_list.remove(50) # output: [10, 30, 40] 

# again converting the my_list back to my_tuple 
my_tuple = tuple(my_list) 


print my_tuple # output: (10, 30, 40) 

Благодаря

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