循环可以在全局框架内引用列表而无需命名吗?

时间:2019-02-12 16:42:51

标签: python loops recursion counter frequency

我受命按频率对列表进行分组。这是关于SOF的一个非常普遍的问题,到目前为止,该论坛的教育程度很高。但是,在给出的所有示例中,只有以下一个示例可以实现:

  • 对给定的可迭代对象进行排序,以便其元素以递减的频率顺序结束。
  • 如果两个元素具有相同的频率,则它们应以与迭代器中第一个外观相同的顺序结束。

使用这两个列表:

[4, 6, 2, 2, 6, 4, 4, 4]
[17, 99, 42]

以下作为解决该问题的通用代码失败。

from collections import Counter
freq = Counter(items)

# Ex 1
# The items dont stay grouped in the final list :(

sorted(items, key = items.count, reverse=True)
sorted(items, key=lambda x: -freq[x])
[4, 4, 4, 4, 6, 2, 2, 6]


# Ex 2
# The order that the items appear in the list gets rearranged :(

sorted(sorted(items), key=freq.get, reverse=True)
[4, 4, 4, 4, 2, 2, 6, 6]


# Ex 3
# With a list of integers, after the quantity gets sorted, 
# the int value gets sorted :(

sorted(items, key=lambda x: (freq[x], x), reverse=True)
[99, 42, 17]

我确实找到了一个行之有效的解决方案:

s_list = sorted(freq, key=freq.get, reverse=True)

new_list = []
for num in s_list:
    for rep in range(freq[num]):
        new_list.append(num)
print(new_list)

我无法弄清楚第二个循环如何引用出现次数。

我通过pythontutor运行了该过程以对其进行可视化,并且代码似乎只知道在“项目”列表中有四个“ 4”,两个“ 6”和两个“ 2”。我能想到的唯一解决方案是python可以在全局框架中引用列表而无需命名。或者也许能够利用“频率”字典中的值。这是正确的吗?

引用的线程: Sort list by frequency in python

1 个答案:

答案 0 :(得分:1)

是的,freq的值使第二个循环起作用。

freqCounter

  

这是一个无序集合,其中元素存储为字典键,其计数存储为字典值。

换句话说,freq是一个字典,其中的键是items的唯一元素,映射到它们在items中出现的次数。

并举例说明:

>>> from collections import Counter
>>> items = [4, 6, 2, 2, 6, 4, 4, 4]
>>> freq = Counter(items)
>>> freq
Counter({4: 4, 6: 2, 2: 2})

因此,在第二个循环中迭代range(freq[num])时,它所做的就是迭代numitems中出现的次数。


编辑2019-02-13: Python导师的其他信息和示例

Python Tutor看起来像按原样表示简单的内置类型(整数,字符串等),而不是在其自己的单元格中表示为“对象”。

如果使用新对象而不是整数,则可以清楚地看到引用。例如,如果要包装整数,例如:

from collections import Counter

class MyIntWrapper:
    def __init__(self, value):
        self.value = value

items = [4, 6, 2, 2, 6, 4, 4, 4]
items_wrapped = [MyIntWrapper(item) for item in items]
freq = Counter(items_wrapped)

s_list = sorted(freq, key=freq.get, reverse=True)

new_list = []
for num in s_list:
    for rep in range(freq[num]):
        new_list.append(num)