Can someone explain the below behavior?

In [23]: l = ['', 'Camino Cielo', '', '']
In [24]: ll = ['', 'Maricopa', 'Highway', '']

In [26]: ' '.join(e for e in l if e)
Out[26]: 'Camino Cielo'

In [27]: ' '.join(e for e in ll if e)
Out[27]: 'Maricopa Highway'

In [29]: glue = ' '
In [30]: '%s'.join(e for e in ll if e) % glue
Out[30]: 'Maricopa Highway'

In [31]: '%s'.join(e for e in l if e) % glue
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
31-7ea8ccb65d69> in <module>()
----> 1 '%s'.join(e for e in l if e) % glue

TypeError: not all arguments converted during string formatting
有帮助吗?

解决方案

The % operator is applied to the result of the str.join() call:

>>> '%s'.join(e for e in ll if e)
'Maricopa%sHighway'
>>> '%s'.join(e for e in ll if e) % glue
'Maricopa Highway'
>>> '%s'.join(e for e in l if e)
'Camino Cielo'

Note that there is no %s in the last result there; there is only one string in the output of the e for e in l if e generator expression, the rest are all empty and don't pass the if e filter.

With no placeholder, you cannot interpolate glue either:

>>> 'Camino Cielo' % glue
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting

You'd also have a problem if you had more than two strings to join:

>>> '%s'.join(['foo', 'bar', 'spam'])
'foo%sbar%sspam'
>>> '%s'.join(['foo', 'bar', 'spam']) % glue
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

In this case, just use glue directly:

>>> glue.join(e for e in ll if e)
'Maricopa Highway'
>>> glue.join(e for e in l if e)
'Camino Cielo'
>>> glue.join(['foo', 'bar', 'spam'])
'foo bar spam'

There is little use for interpolating when all your template consists of is '%s'.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top