2010-12-14 11 views
29

Ich weiß, SieGibt es in Python eine elegante Möglichkeit, eine Liste in einem benutzerdefinierten Format ohne explizites Looping zu drucken?

tun können
print str(myList) 

[1, 2, 3] 

zu erhalten und Sie können tun

i = 0 
for entry in myList: 
    print str(i) + ":", entry 
    i += 1 

0: 1 
1: 2 
2: 3  

zu bekommen, aber ist es eine Möglichkeit, ähnlich wie Der Erste um ein ähnliches Ergebnis zu erhalten?

Mit meiner begrenzten Kenntnis von Python (und etwas Hilfe von der Dokumentation), mein bestes ist:

print '\n'.join([str(n) + ": " + str(entry) for (n, entry) in zip(range(0,len(myList)), myList)]) 

Es ist nicht viel weniger ausführlich, aber zumindest ich eine benutzerdefinierte Zeichenfolge in einer (Verbindung) Anweisung erhalten . Können Sie es besser machen?

Antwort

75
>>> lst = [1, 2, 3] 
>>> print('\n'.join('{}: {}'.format(*k) for k in enumerate(lst))) 
0: 1 
1: 2 
2: 3 

Hinweis: Sie müssen nur diese Liste Verständnis verstehen oder einen Generator Ausdruck iterieren ist explizite Looping.

+4

+1 dafür; Ich kenne Python ziemlich gut und das ist einfach schön, einfach und sauber –

+3

Genauer gesagt: Wenn Sie die eckigen Klammern verlieren, wird es zu einem Generatorausdruck, sodass nicht die gesamte Liste im Speicher erstellt wird, bevor eine Zeichenfolge daraus erstellt wird. Und enumerate ist eine eingebaute Funktion, um das selbe wie die Zip/range/len Combo des Posters zu machen. –

+0

+1 ich mag Format und Aufzählung verwenden;) – Ant

8
l = [1, 2, 3] 
print '\n'.join(['%i: %s' % (n, l[n]) for n in xrange(len(l))]) 
+8

Ich bin schockiert, wie viele Menschen scheinbar nicht 'enumerate' wissen. – delnan

+0

@delnan: Ich weiß es auch nicht, wahrscheinlich weil ich Python nicht genug verwende (Tests und Scripting). Ich werde jetzt nachsehen. – stefaanv

+0

Ja in der Tat, nützliches Wissen :) Ich habe die andere auf den neuesten Stand gebracht;) –

2

Ein anderer:

>>> lst=[10,11,12] 
>>> fmt="%i: %i" 
>>> for d in enumerate(lst): 
... print(fmt%d) 
... 
0: 10 
1: 11 
2: 12 

Noch eine andere Form:

>>> for i,j in enumerate(lst): print "%i: %i"%(i,j) 

Diese Methode ist schön, da die einzelnen Elemente in durch enumerate erzeugt Tupeln modifiziert werden können, wie:

>>> for i,j in enumerate([3,4,5],1): print "%i^%i: %i "%(i,j,i**j) 
... 
1^3: 1 
2^4: 16 
3^5: 243 

Natürlich vergessen Sie nicht, dass Sie ein Stück von diesem wie so bekommen kann:

>>> for i,j in list(enumerate(lst))[1:2]: print "%i: %i"%(i,j) 
... 
1: 11 
+0

Es ist nichts falsch mit expliziten Schleifen.Ich habe mich nur gefragt, was die Alternativen sind. – stefaanv

3
from time import clock 
from random import sample 

n = 500 
myList = sample(xrange(10000),n) 
#print myList 

A,B,C,D = [],[],[],[] 

for i in xrange(100): 
    t0 = clock() 
    ecr =('\n'.join('{}: {}'.format(*k) for k in enumerate(myList))) 
    A.append(clock()-t0) 

    t0 = clock() 
    ecr = '\n'.join(str(n) + ": " + str(entry) for (n, entry) in zip(range(0,len(myList)), myList)) 
    B.append(clock()-t0) 

    t0 = clock() 
    ecr = '\n'.join(map(lambda x: '%s: %s' % x, enumerate(myList))) 
    C.append(clock()-t0) 

    t0 = clock() 
    ecr = '\n'.join('%s: %s' % x for x in enumerate(myList)) 
    D.append(clock()-t0) 

print '\n'.join(('t1 = '+str(min(A))+' '+'{:.1%}.'.format(min(A)/min(D)), 
       't2 = '+str(min(B))+' '+'{:.1%}.'.format(min(B)/min(D)), 
       't3 = '+str(min(C))+' '+'{:.1%}.'.format(min(C)/min(D)), 
       't4 = '+str(min(D))+' '+'{:.1%}.'.format(min(D)/min(D)))) 

Für n = 500:

150.8%. 
142.7%. 
110.8%. 
100.0%. 

Für n = 5000:

153.5%. 
176.2%. 
109.7%. 
100.0%. 

Oh, ich sehe jetzt: nur die Lösung 3 mit map() passt zum Titel der Frage.

+0

Schöne Forschung. Generator-Ausdruck ist kein expliziter Looping, also zählen sie alle zu den Favoriten 1 und 4, wobei 1 eine leistungsfähigere, aber wie hier eine langsamere Formatierung verwendet. Merci. – stefaanv

+1

['timeit'] (http://docs.python.org/library/timeit.html) – SilentGhost

4
>>> from itertools import starmap 

>>> lst = [1, 2, 3] 
>>> print('\n'.join(starmap('{}: {}'.format, enumerate(lst)))) 
0: 1 
1: 2 
2: 3 

Dies verwendet itertools.starmap, die wie map ist, außer es * s das Argument in der Funktion. Die Funktion ist in diesem Fall '{}: {}'.format.

Ich würde das Verständnis von SilentGhost bevorzugen, aber starmap ist eine nette Funktion zu wissen.

4

In Python 3s Druckfunktion:

lst = [1, 2, 3] 
print('My list:', *lst, sep='\n- ') 

Ausgang:

My list: 
- 1 
- 2 
- 3 

Con: Die sep muss eine Zeichenfolge sein, so dass Sie es nicht ändern können, basierend auf welchem ​​Element Sie‘ erneut drucken. Und Sie brauchen eine Art von Header, um dies zu tun (darüber war 'My list:').

Pro: Sie müssen keine join() eine Liste in einem String-Objekt, die für größere Listen von Vorteil sein könnte. Und das Ganze ist sehr präzise und lesbar.

3

von diesem Start:

>>> lst = [1, 2, 3] 
>>> print('\n'.join('{}: {}'.format(*k) for k in enumerate(lst))) 
0: 1 
1: 2 
2: 3 

Sie können der join durch \n vorbei als Separator zu print

>>> print(*('{}: {}'.format(*k) for k in enumerate(lst)), sep="\n") 
0: 1 
1: 2 
2: 3 

Nun, Sie map verwenden konnte sehen, loszuwerden, aber Sie brauchen um die Formatzeichenkette zu ändern (yuck!)

>>> print(*(map('{0[0]}: {0[1]}'.format, enumerate(lst))), sep="\n") 
0: 1 
1: 2 
2: 3 

oder 2 Sequenzen an map übergeben. Ein separater Zähler und nicht mehr zählen lst

>>> from itertools import count 
>>> print(*(map('{}: {}'.format, count(), lst)), sep="\n") 
0: 1 
1: 2 
2: 3 
Verwandte Themen