【问题标题】:Unique Combinations in a list of k,v tuples in PythonPython中k,v元组列表中的唯一组合
【发布时间】:2015-07-28 15:12:17
【问题描述】:

我有一个元组中各种项目组合的列表

example = [(1,2), (2,1), (1,1), (1,1), (2,1), (2,3,1), (1,2,3)]

我希望按唯一组合进行分组和计数

产生结果

result = [((1,2), 3), ((1,1), 2), ((2,3,1), 2)]

保持顺序或保留组合的哪个排列不重要,但使用 lambda 函数完成操作非常重要 并且输出格式仍然是上面的元组列表,因为我将使用 spark RDD 对象

我的代码目前使用

计算从数据集中获取的模式

RDD = sc.parallelize(example) result = RDD.map(lambda(y):(y, 1))\ .reduceByKey(add)\ .collect() print result

我需要另一个 .map 命令来为不同的排列添加帐户,如上所述

【问题讨论】:

  • 结果顺序重要吗?
  • 顺序无所谓
  • 是什么让您认为任何使用 lambda 都比简单循环更快?至少在 Python 中情况正好相反。
  • 我需要使用 lambda 函数来完成,因为我使用的是 spark RDD,我真的不明白这些东西是如何工作的,所以我需要非常小心数据类型我通过了,我会再次尝试更新问题
  • 听起来像XY-problem。您似乎需要一种 map-reduce 之类的东西。

标签: python list lambda apache-spark tuples


【解决方案1】:

怎么样:维护一个集合,其中包含您已经看到的每个项目的排序形式。如果您还没有看到它的排序形式,请仅将项目添加到结果列表中。

example = [ ('a','b'), ('a','a','a'), ('a','a'), ('b','a'), ('c', 'd'), ('b','c','a'), ('a','b','c') ]
result = []
seen = set()
for item in example:
    sorted_form = tuple(sorted(item))
    if sorted_form not in seen:
        result.append(item)
        seen.add(sorted_form)
print result

结果:

[('a', 'b'), ('a', 'a', 'a'), ('a', 'a'), ('c', 'd'), ('b', 'c', 'a')]

【讨论】:

  • 打败我 - 我就是这样做的。
【解决方案2】:

您可以使用OrderedDict 根据其项目的排序大小写创建一个有序字典:

>>> from collections import OrderedDict
>>> d=OrderedDict()
>>> for i in example:
...   d.setdefault(tuple(sorted(i)),i)
... 
('a', 'b')
('a', 'a', 'a')
('a', 'a')
('a', 'b')
('c', 'd')
('b', 'c', 'a')
('b', 'c', 'a')
>>> d
OrderedDict([(('a', 'b'), ('a', 'b')), (('a', 'a', 'a'), ('a', 'a', 'a')), (('a', 'a'), ('a', 'a')), (('c', 'd'), ('c', 'd')), (('a', 'b', 'c'), ('b', 'c', 'a'))])
>>> d.values()
[('a', 'b'), ('a', 'a', 'a'), ('a', 'a'), ('c', 'd'), ('b', 'c', 'a')]

【讨论】:

  • d.setdefault(tuple(sorted(i)), i) 不够吗?
  • 甚至d.setdefault(frozenset(i), i)。
  • @bereal 是的,这是一个更好的主意!
【解决方案3】:

这类似于排序的字典。

from itertools import groupby
ex = [(1,2,3), (3,2,1), (1,1), (2,1), (1,2), (3,2), (2,3,1)]
f = lambda x: tuple(sorted(x)) as key
[tuple(k) for k, _ in groupby(sorted(ex, key=f), key=f)]

好消息是你可以得到哪些元组是相同的组合:

In [16]: example = [ ('a','b'), ('a','a','a'), ('a','a'), ('a', 'a', 'a', 'a'), ('b','a'), ('c', 'd'), ('b','c','a'), ('a','b','c') ]
In [17]: for k, grpr in groupby(sorted(example, key=lambda x: tuple(sorted(x))), key=lambda x: tuple(sorted(x))):
    print k, list(grpr)
   ....:     
('a', 'a') [('a', 'a')]
('a', 'a', 'a') [('a', 'a', 'a')]
('a', 'a', 'a', 'a') [('a', 'a', 'a', 'a')]
('a', 'b') [('a', 'b'), ('b', 'a')]
('a', 'b', 'c') [('b', 'c', 'a'), ('a', 'b', 'c')]
('c', 'd') [('c', 'd')]

【讨论】:

    【解决方案4】:

    根据 cmets,您实际上似乎需要的是 map-reduce。我没有安装 Spark,但根据文档(请参阅 transformations),它必须是这样的:

    data.map(lambda i: (frozenset(i), i)).reduceByKey(lambda _, i : i)
    

    但是,如果您的数据集按该顺序包含 (a, b), (b, a),这将返回 (b, a)。

    【讨论】:

    • 我刚刚更新了这个问题,希望能对您有所帮助
    • 是的,你是对的,这是一个 x,y 的事情,我用类似的方法解决了这个问题我应该发布我的解决方案还是应该删除我的问题?再次感谢所有帮助,如果没有这些建议,我将无法解决它
    • @PeterDoro you cannot 删除一个带有赞成票的问题。您可以提供自己的答案并接受它,以便人们看到该主题已关闭。
    【解决方案5】:

    我解决了自己的问题,但很难理解我真正在寻找我使用的是什么

    example = [(1,2), (1,1,1), (1,1), (1,1), (2,1), (3,4), (2,3,1), (1,2,3)]
    RDD = sc.parallelize(example)
    result = RDD.map(lambda x: list(set(x)))\
                .filter(lambda x: len(x)>1)\
                .map(lambda(x):(tuple(x), 1))\
                .reduceByKey(add)\
                .collect()
    print result
    

    这也消除了简单的重复值,例如 (1,1) 和 (1,1,1),这对我有额外的好处

    【讨论】:

      【解决方案6】:

      由于您正在寻找 lambda 函数,请尝试以下操作:

      lambda x, y=OrderedDict(): [a for a in x if y.setdefault(tuple(sorted(a)), a) and False] or y.values()
      

      你可以像这样使用这个 lambda 函数:

      uniquify = lambda x, y=OrderedDict(): [a for a in x if y.setdefault(tuple(sorted(a)), a) and False] or y.values()
      result = uniquify(example)
      

      显然,这牺牲了其他答案的可读性。它基本上和 Kasramvd 的回答一样,只是一条丑陋的线。

      【讨论】:

      • 对不起,我真的是 python 新手,你能告诉我这将如何进入我的列表example
      • 您将首先为 lambda 函数设置一个变量,如下所示:uniquify = lambda x, y=OrderedDict(): [a for a in x if y.setdefault(tuple(sorted(a)), a) and False] or y.values()。然后,使用您的列表作为参数调用该函数,如下所示:result = uniquify(example)。我已更新我的答案以包含此信息。
      猜你喜欢
      • 1970-01-01
      • 2019-05-25
      • 1970-01-01
      • 2017-10-09
      • 2013-08-14
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多