开发者

In Python, is there an elegant way to print a list in a custom format without explicit looping?

I know you can do

print str(myList)

to get

[1, 2, 3]

and you can do

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

to get

0: 1  
1: 2  
2: 3    

But 开发者_运维技巧is there a way similar to the first to get a result similar to the last?

With my limited knowledge of Python (and some help from the documentation), my best is:

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

It's not much less verbose, but at least I get a custom string in one (compound) statement. Can you do better?


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

Note: you just need to understand that list comprehension or iterating over a generator expression is explicit looping.


In python 3s print function:

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

Output:

My list:
- 1
- 2
- 3

Con: The sep must be a string, so you can't modify it based on which element you're printing. And you need a kind of header to do this (above it was 'My list:').

Pro: You don't have to join() a list into a string object, which might be advantageous for larger lists. And the whole thing is quite concise and readable.


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


Starting from this:

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

You can get rid of the join by passing \n as a separator to print

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

Now you see you could use map, but you'll need to change the format string (yuck!)

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

or pass 2 sequences to map. A separate counter and no longer enumerate lst

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


>>> from itertools import starmap

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

This uses itertools.starmap, which is like map, except it *s the argument into the function. The function in this case is '{}: {}'.format.

I would prefer the comprehension of SilentGhost, but starmap is a nice function to know about.


Another:

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

Yet another form:

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

That method is nice since the individual elements in tuples produced by enumerate can be modified such as:

>>> 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 

Of course, don't forget you can get a slice from this like so:

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


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))))

For n=500:

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

For n=5000:

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

Oh, I see now: only the solution 3 with map() fits with the title of the question.


Take a look on pprint, The pprint module provides a capability to “pretty-print” arbitrary Python data structures in a form which can be used as input to the interpreter. If the formatted structures include objects which are not fundamental Python types, the representation may not be loadable. This may be the case if objects such as files, sockets or classes are included, as well as many other objects which are not representable as Python literals.

>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff[:])
>>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(stuff)
[   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
    'spam',
    'eggs',
    'lumberjack',
    'knights',
    'ni']
>>> pp = pprint.PrettyPrinter(width=41, compact=True)
>>> pp.pprint(stuff)
[['spam', 'eggs', 'lumberjack',
  'knights', 'ni'],
 'spam', 'eggs', 'lumberjack', 'knights',
 'ni']
>>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
... ('parrot', ('fresh fruit',))))))))
>>> pp = pprint.PrettyPrinter(depth=6)
>>> pp.pprint(tup)
('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜