匹配列表中的第一个和最后一个项目

时间:2017-10-23 19:44:30

标签: python

我的目标是遍历名单列表并返回True,只要它们可以排列,以便名称的最后一个字母与下一个名字的第一个字母相同。

class Team(object):
    def __init__(self, names):
        self.names = names

    def __iter__(self):
        from collections import Counter
        first = Counter(map(lambda n: n[0].lower(), self.names))
        last = Counter(map(lambda n: n[-1].lower(), self.names))
        diff = last - first
        return any(diff.values()) <= 1

def isCoolTeam(team):
    return bool(Team(team))

print(isCoolTeam(["Rob", 
 "Bobby", 
 "Billy"]))

它应该返回False,但由于某种原因,每个输入都返回true。

3 个答案:

答案 0 :(得分:2)

函数any()返回booleanTrue / False),所有booleans 小于等于<=1

这意味着line

return any(diff.values()) <= 1

始终评估为True

答案 1 :(得分:0)

以下是一些修改。将Team转换为布尔值似乎没有意义,因此我不会定义__bool__,而是明确定义is_cool

另外,我想你想检查一下是否有差异高于1.在这种情况下,你需要all(v <= 1 for v in diff.values())

class Team(object):
    def __init__(self, names):
        self.names = names

    def is_cool(self):
        from collections import Counter
        first = Counter(map(lambda n: n[0].lower(), self.names))
        last = Counter(map(lambda n: n[-1].lower(), self.names))
        diff = last - first
        return all(v <= 1 for v in diff.values())

print(Team(["Rob", "Bobby", "Billy"]).is_cool())
# False
print(Team(["Rob", "Nick", "Bobby", "Yann"]).is_cool())
# True

但逻辑仍存在(大)问题:

print(Team(["Ab", "cd", "ef"]).is_cool())
# True

我不认为Counter足以解决这个问题。您可能需要定义一个图表,看看是否有连接每个名称的路径。 NetworkX可能有帮助。

以下是related graph problem的说明。

答案 2 :(得分:0)

您的问题是配对元素之一。您希望将特定的第一个字母与相应的最后一个字母一遍又一遍地匹配,直到所有名称都用完为止。

如果您考虑一下,当您完成后,您将在开始时有一个未配对的首字母,最后一封未配对的最后一封信:

Rob-&GT; Bobby-&GT; Yannick-&GT; Karl-&GT; Luigi-&GT; Igor-&GT; Renee-&GT; Edmund-&GT;大卫 - &GT;提奥奇尼斯

这意味着字母计数的减法应该是1,在两个方向上:应该有1个首字母不匹配,1个最后一个字母不匹配(第一个 - 最后一个,最后一个)。 但是,如果有重复的字母,即使这可能还不够。您想检查列表的长度(以确保它有效),然后检查差异是&lt; = 1。

假设您有一个长度为0的列表:第一个/最后一个字母的计数将为空,但列表太短。

假设你有一个长度为1的列表:第一个/最后一个字母的数量将是1和1,符合要求。

假设您有一个长度为2的列表:

  • 假设没有重叠:[&#39; rob&#39;,&#39; diane&#39;]那么第一个/最后一个字母的总计数将是2和2,违反了要求。

  • 假设没有重叠,但共享信件:[&#39; brad&#39;,&#39; betty&#39;]那么第一个/最后一个字母的总计数将是2和2 ,但安排不同。我想你应该总结一下。 ; - )

  • 假设存在完全重叠:[&#39; bob&#39;,&#39; bob&#39;]。这留下了空的减法,符合要求。

  • 假设存在部分重叠:[&#39; bob&#39;,&#39; betty&#39;]。这会分别留下{b:1}和{y:1}的计数,因此它可以正常工作。

您必须处理差异为空的情况,其中差异包含一个包含2+计数的元素,并且差异具有多个具有1或更多计数的元素。

我认为你不想any()。我认为你需要某种聚合功能。我怀疑sum()会起作用。