仅当名称长于其前一个时才打印。

| 假设您有一个名称列表[\“ sam \”,\“ janet \”,\“ bob \”,\“ samantha \”]。 您将如何用Python编写程序,使其仅在名称长于其名称时才打印名称。     
已邀请:
itertools
中的
pairwise
配方与列表理解一起使用,这让我印象深刻:
>>> from itertools import izip, tee
>>> def pairwise(iterable):
...     \"s -> (s0,s1), (s1,s2), (s2, s3), ...\"
...     a, b = tee(iterable)
...     next(b, None)
...     return izip(a, b)
...
>>> namelist = [\"sam\", \"janet\", \"bob\",\"samantha\"]
>>> [b for a,b in pairwise(namelist) if len(b) > len(a)]
[\'janet\', \'samantha\']
更新资料 从您的问题尚不清楚,ѭ3中的名字是否应该比前面的名字更长或更短。上述解决方案将其排除在外。如果您(或您的老师?)想要包括第一项:
>>> [namelist[0]] + [b for a,b in pairwise(namelist) if len(b) > len(a)]
[\'sam\', \'janet\', \'samantha\']
    
a = [\"sam\", \"janet\", \"bob\", \"samantha\"]

# two similar one-liners:
print \', \'.join(a2 for a1, a2 in zip(a[:-1],a[1:]) if len(a2) > len(a1))
print \', \'.join(a[i] for i in xrange(1, len(a)) if len(a[i]) > len(a[i-1]))

# output of both of them:
janet, samantha
    
到目前为止,只有5个答案。他们都没有打印名字。当然,可以很容易地对许多方法进行更改,但是就此而言,这里就是这样做的。我会很好地分解它。 python itertools模块是自十一英尺以来最伟大的事情,而对此问题特别有希望的迭代器是
ifilter
,它在列表中的每个项目上调用给定函数,并且仅输出该函数返回outputs7的那些函数。所以我们想做这样的事情:
from itertools import ifilter

names = [\"sam\", \"janet\", \"bob\", \"jane\", \"samantha\"]
for name in ifilter(longer_than_previous, names):
    print name   # Output: sam (?), janet, jane, samantha
因此,我们尚未定义的函数
longer_than_previous
将首先使用\“ sam \”作为参数,然后调用\“ janet \”,\“ bob \”,依此类推。现在的问题是函数通常没有内存,因此我们需要一些技巧来使函数记住最后一个参数的长度并将其与当前参数的长度进行比较。 做到这一点的天真的方法是在全球范围内争论。假设以下代码粘贴在上面给出的代码之前:
last_name_length = 0

def longer_than_previous(name):
    global last_name_length
    is_longer = len(name) > last_name_length
    last_name_length = len(name)
    return is_longer
现在,使用全局变量存储实际上只需要在一个地方使用的值被认为是不好的做法。有没有其他方法可以给我们的功能记忆?好吧,在python中,一切都是对象,因此我们可以给函数本身一个属性(警告,前面的丑陋代码):
def longer_than_previous(name):
    if not hasattr(longer_than_previous, \"last_name_length\"):
        longer_than_previous.last_name_length = 0
    is_longer = len(name) > longer_than_previous.last_name_length
    longer_than_previous.last_name_length = len(name)
    return is_longer
好吧,这并不能完全提高可读性,我们必须使用
hasattr
,我发现这很好地表明了我的设计不好。另外,此功能仅可使用一次,之后我们必须用
longer_than_previous.last_name_length = 0
手动将其复位。因此,我们希望能够像这样创建一些一次性函数,每个函数都有一个用于存储最后长度的属性。嗯,这对于一个类来说听起来不错。毕竟,类是在被调用时产生具有属性的对象的东西。但是对象需要像函数一样起作用。我们可以使用
__call__
特殊方法来实现,如下所示:
class LongerThanPrevious(object):
    def __init__(self):
        self.last_name_length = 0

    def __call__(self, name):
        is_longer = len(name) > self.last_name_length
        self.last_name_length = len(name)
        return is_longer
现在,我们只需要更改顶部的代码,即可使用
LongerThanPrevious
类的对象而不是功能long_than_previous:
for name in ifilter(LongerThanPrevious(), names):
    print name   # Output: sam (?), janet, jane, samantha
现在,这已经好得多了,而且可读性强。我在sam后面加了一个问号,因为这个问题尚待解决。更改类很容易,因此不包括在内:
    def __init__(self):
        self.last_name_length = float(\"infinity\")
注意:答案已被完全重写。     
直截了当:
oldlen=0
for f in [\"vusi\", \"angelina\", \"uma\", \"johnny\", \"sizwe\", \"kate\", \"charlize\", \"meryl\"]:
    x=len(f) 
    if x>oldlen:
        print(f)
    oldlen=x
想法是将先前打印的长度存储在变量中。     
我会尝试这样的:
names = [\"sam\", \"janet\", \"bob\",\"samantha\"]
last_name = None
for name in names:
    if last_name and len(name) > len(last_name):
        print name
    last_name = name
或者(以更Python化的方式):
names = [\"sam\", \"janet\", \"bob\",\"samantha\"]
print \'\\n\'.join(name for i, name in enumerate(names) if i>0 and len(name) > len(names[i-1]))
当然,名字永远不会被打印出来。     

要回复问题请先登录注册