2016-04-29 3 views
2

У меня есть кортежи произвольного размера. Это пример:Удалить следующие дубликаты в кортеже

ax = ('0','1','1','1','2','2','2','3') 

Для маркировки оси х Я хочу, чтобы преобразовать этот кортеж:

ax = ('0','1','','','2','','','3') 

Так дубликаты должны быть удалены в то время как размер кортежа должен оставаться такими же. Есть ли простой способ сделать это?

+1

Просто маленькая вещь: я считаю, что это кортеж, а не список. Есть некоторые тонкие различия, но для этого вопроса это может не иметь значения. – dvaergiller

ответ

4
In [12]: seen = set() 

In [13]: [x if x not in seen and not seen.add(x) else '' for x in ax] 
Out[13]: ['0', '1', '', '', '2', '', '', '3'] 

Это немного измененная версия uniquifier предложенной Dave Kirby, here.


seen.add(x) добавляет x множеству seen. Метод seen.add возвращает None. Итак, в булевом контексте, (с bool(None) - False), not seen.add(x) всегда True. Поэтому условие

x not in seen and not seen.add(x) 

имеет логическое значение, равное

x not in seen and True 

, которое эквивалентно

x not in seen 

Так условное выражение

x if x not in seen and not seen.add(x) else '' 

возвращается, если x еще не находится в seen и возвращает '', если x уже в seenx затем добавляется к seen). Если x not in seen является False (то есть, если x уже в seen), то seen.add(x) не вызывается, потому что and короткого замыкания языка Python - любое выражение вида False and something автоматически False без одного, имеющего оценить something.


Это также может быть написан, а не сжато, но без сложности, так как

def replace_dupes(ax): 
    result = [] 
    seen = set() 
    for x in ax: 
     if x in seen: 
      result.append('') 
     else: 
      seen.add(x) 
      result.append(x) 
    return result 

ax = ('0','1','1','1','2','2','2','3') 
print(replace_dupes(ax)) 
# ['0', '1', '', '', '2', '', '', '3'] 
+2

что 'не видел.add (x)' делает? –

+0

'Функция добавления возвращает None', это только для set? –

+0

Методы Python из стандартной библиотеки обычно следуют [Принцип разделения командного запроса] (https://en.wikipedia.org/wiki/Command%E2%80%93query_separation). Методы, которые изменяют объект (т.команды) возвращает 'None', тогда как методы, которые запрашивают объект, возвращают значение и не имеют побочных эффектов. 'list.sort' и' dict.update' также являются примерами методов, которые изменяют объект и возвращают 'None'. – unutbu

1

Если вы просто ищете соседние дубликаты, то вы могли бы использовать groupby функции Пайтона следующим образом :

from itertools import groupby 

ax = ['0', '1', '1', '1', '2', '2', '2', '3'] 
ax_output = [] 

for k, g in groupby(ax): 
    ax_output.extend([k] + [''] * (len(list(g))-1)) 

print ax_output 

Это даст вам следующий список:

['0', '1', '', '', '2', '', '', '3']  
Смежные вопросы