2010-03-15 16 views
19

Ich möchte eine Funktion schreiben, die eine Liste [1,5,3,6,...] wiederbelebt und gibt [1,1,5,5,3,3,6,6,...] eine Idee, wie es geht? dankduplizieren jedes Mitglied in einer Liste - Python

+2

Klingt heimlich. Es gibt bessere Möglichkeiten, mit einer Liste zu arbeiten, als die Elemente zu duplizieren. –

Antwort

12
>>> a = [1, 2, 3] 
>>> b = [] 
>>> for i in a: 
    b.extend([i, i]) 


>>> b 
[1, 1, 2, 2, 3, 3] 

oder

>>> [a[i//2] for i in range(len(a)*2)] 
[1, 1, 2, 2, 3, 3] 
+0

Sie sollten '' '' '' auch für die Floor Division in Python 2 verwenden. –

+0

@Mike: Sicher hast du Recht, außer natürlich in '/' division versichert, dass 'int' zurückgegeben wird. – SilentGhost

38
>>> a = range(10) 
>>> [val for val in a for _ in (0, 1)] 
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9] 

N. B. _ wird traditionell als Name einer Platzhaltervariablen verwendet, wenn Sie nichts mit dem Inhalt der Variablen tun möchten. In diesem Fall wird es nur verwendet, um zwei Werte für jedes Mal um die äußere Schleife herum zu erzeugen.

Um dies von einer Liste in einen Generator zu verwandeln, ersetzen Sie die eckigen Klammern durch runde Klammern.

+1

'_' wird heute für i18n/l10n (google) verwendet. Ich tendiere immer noch dazu, es zu benutzen, wenn ich weiß, dass es in diesem Modul kein i18n geben wird. Sonst würde ich "__" (zwei Unterstriche) verwenden. –

1

Ich würde verwenden

import itertools 
foo = [1, 5, 3, 6] 
new = itertools.chain.from_iterable([item, item] for item in foo) 

new wird ein Iterator, lazily iteriert über den duplizierten Elemente sein. Wenn Sie die tatsächliche Liste berechnet benötigen, können Sie list(new) tun oder eine der anderen Lösungen verwenden.

+1

oder kürzer: 'itertools.chain.from_iterable (itertools.izip (foo, foo))' –

+0

Ich dachte, dass Code, der kürzer ist, aber mir nicht klarer schien. –

6

Wenn Sie bereits die für itertools in der Dokumentation beschrieben roundrobin Rezept haben -und es ist recht praktisch-dann können Sie nur

roundrobin(my_list, my_list) 
+0

+1, dies ist ein guter Weg, dies zu erreichen. –

1

Für so viel verwenden, wie Guido die funktionellen Operatoren Abneigungen, können sie recht sein verflixte praktisch:

>>> from operator import add 
>>> a = range(10) 
>>> b = reduce(add, [(x,x) for x in a]) 
+0

Im Fall von reduzieren bedeutet handy oft erstaunlich langsam. Es ist wichtig zu messen, was reduce macht. Oft ist es schockierend, wie viel Rechenleistung die Kräfte reduziert. –

+0

Ich habe ein Testskript mit jeder der Methoden auf dieser Seite mit der Basisliste = Bereich (10) und 1.000.000 Iterationen gemacht. Der langsamste dauerte 5.094 Sekunden und der schnellste dauerte 3.622 Sekunden. Mein reduziertes Beispiel dauerte 3.906 Sekunden. –

+1

'Bereich (10)' ist winzig, so dass die Komplexität eine kleine Rolle spielt. Diese Lösung ist quadratisch; Alle anderen, die ich hier sehe, sind linear. Außerdem scheinen mir einige der anderen lesbarer zu sein. –

8

würde ich zip und itertools.chain verwenden.

>>> import itertools 
>>> l = [1,5,3,6,16] 
>>> list(itertools.chain(*zip(l,l))) 
[1, 1, 5, 5, 3, 3, 6, 6, 16, 16] 

Hinweis: Früher habe ich nur list den Generator verbrauchen, um es für den Druck fit zu machen. Sie brauchen wahrscheinlich nicht den list Anruf in Ihrem Code ...

1

Es ist möglich, verwenden Sie die Liste Multiplikation. Falls Sie jedes Listenelement zusammen benötigen, verwenden Sie einfach die sortierte Methode.

>>> lst = [1,2,3,4] 
>>> sorted(lst*2) 
[1,1,2,2,3,3,4,4] 
+0

Was ist, wenn Sie die Reihenfolge der ursprünglichen Liste beibehalten möchten? Was ist, wenn die Elemente in der Liste nicht mehr zuordenbar sind? – Moberg

Verwandte Themen