سؤال

أريد ترتيب قوائم متعددة وفقا لعناصرهم كم عدد مرات ظهورها في كل قائمة. مثال:

List1 = 1،2،3،4.
List2 = 4،5،6،7.
list3 = 4،1،8،9.

النتيجة = 4،1،2،3،4،5،6،6،6،8 (4 يحسب ثلاث مرات، 1 مرتين والباقي مرة واحدة)

لقد جربت ما يلي ولكني بحاجة إلى شيء أكثر ذكاء وشيء يمكنني القيام به مع أي القوائم.


 l = []
 l.append([ 1, 2, 3, 4, 5])
 l.append([ 1, 9, 3, 4, 5])
 l.append([ 1, 10, 8, 4, 5])
 l.append([ 1, 12, 13, 7, 5])
 l.append([ 1, 14, 13, 13, 6])

 x1 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[3])
 x2 = set(l[0]) & set(l[1]) & set(l[2]) & set(l[4])
 x3 = set(l[0]) & set(l[1]) & set(l[3]) & set(l[4])
 x4 = set(l[0]) & set(l[2]) & set(l[3]) & set(l[4])
 x5 = set(l[1]) & set(l[2]) & set(l[3]) & set(l[4])
 set1 = set(x1) | set(x2) | set(x3) | set(x4) | set(x5)

 a1 = list(set(l[0]) & set(l[1]) & set(l[2]) & set(l[3]) & set(l[4]))
 a2 = getDifference(list(set1),a1)
 print a1
 print a2

الآن هنا هي المشكلة ... يمكنني أن أفعل ذلك مرارا وتكرارا مع A3 و A4 و A5 ولكنها معقدة للغاية إذن، أحتاج إلى وظيفة لهذا ... لكنني لا أعرف كيف ... الرياضيات عالقة ؛)

حلها: شكرا جزيلا للمناقشة. كأبى أحب هذا النظام بطريقة أو بأخرى: سريع + بالمعلومات. لقد ساعدني كل شيء! طن

هل كانت مفيدة؟

المحلول

import collections

data = [
  [1, 2, 3, 4, 5],
  [1, 9, 3, 4, 5],
  [1, 10, 8, 4, 5],
  [1, 12, 13, 7, 5],
  [1, 14, 13, 13, 6],
]

def sorted_by_count(lists):
  counts = collections.defaultdict(int)
  for L in lists:
    for n in L:
      counts[n] += 1

  return [num for num, count in
          sorted(counts.items(),
                 key=lambda k_v: (k_v[1], k_v[0]),
                 reverse=True)]

print sorted_by_count(data)

الآن دعونا تعميمها (لاتخاذ أي متطلبات قابلة للتوجيهية وتخفيف)، اسمح لمعايير المفتاح والعكس (لمطابقة فرزها)، وإعادة تسمية freq_sorted.:

def freq_sorted(iterable, key=None, reverse=False, include_freq=False):
  """Return a list of items from iterable sorted by frequency.

  If include_freq, (item, freq) is returned instead of item.

  key(item) must be hashable, but items need not be.

  *Higher* frequencies are returned first.  Within the same frequency group,
  items are ordered according to key(item).
  """
  if key is None:
    key = lambda x: x

  key_counts = collections.defaultdict(int)
  items = {}
  for n in iterable:
    k = key(n)
    key_counts[k] += 1
    items.setdefault(k, n)

  if include_freq:
    def get_item(k, c):
      return items[k], c
  else:
    def get_item(k, c):
      return items[k]

  return [get_item(k, c) for k, c in
          sorted(key_counts.items(),
                 key=lambda kc: (-kc[1], kc[0]),
                 reverse=reverse)]

مثال:

>>> import itertools
>>> print freq_sorted(itertools.chain.from_iterable(data))
[1, 5, 4, 13, 3, 2, 6, 7, 8, 9, 10, 12, 14]
>>> print freq_sorted(itertools.chain.from_iterable(data), include_freq=True)
# (slightly reformatted)
[(1, 5),
 (5, 4),
 (4, 3), (13, 3),
 (3, 2),
 (2, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1), (12, 1), (14, 1)]

نصائح أخرى

الجمع بين اثنين من الأفكار نشرت بالفعل:

from itertools import chain
from collections import defaultdict

def frequency(*lists):
    counter = defaultdict(int)
    for x in chain(*lists):
        counter[x] += 1
    return [key for (key, value) in 
        sorted(counter.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)]

ملاحظات:

  1. في بيثون 2.7، يمكنك استخدام Counter بدلا من defaultdict(int).
  2. يأخذ هذا الإصدار أي عدد من القوائم كوسيطة لها؛ العلامة النجمية الرائدة تعني أن تكون جميعا معبأة في tuple. إذا كنت ترغب في تمرير قائمة واحدة تحتوي على جميع قوائمك، حذفت تلك النجمة الرائدة.
  3. هذا الاستراحات إذا كانت قوائمك تحتوي على نوع غير قابل للنشر.
def items_ordered_by_frequency(*lists):

    # get a flat list with all the values
    biglist = []
    for x in lists:
        biglist += x

    # sort it in reverse order by frequency
    return sorted(set(biglist), 
                  key=lambda x: biglist.count(x), 
                  reverse=True)

جرب هذه:

def rank(*lists):
    d = dict()
    for lst in lists:
        for e in lst:
            if e in d: d[e] += 1
            else: d[e] = 1
    return [j[1] for j in sorted([(d[i],i) for i in d], reverse=True)]

مثال الاستخدام:

a = [1,2,3,4]
b = [4,5,6,7]
c = [4,1,8,9]

print rank(a,b,c)

يمكنك استخدام أي عدد من القوائم كمدخلات

يمكنك حساب عدد مظاهر كل عنصر (رسم بياني)، ثم الترتيب حسب ذلك:

def histogram(enumerable):
  result = {}
  for x in enumerable:
    result.setdefault(x, 0)
    result[x] += 1
  return result

lists = [ [1,2,3,4], [4,5,6,7], ... ]

from itertools import chain

h = histogram(chain(*lists))
ranked = sorted(set(chain(*lists)), key = lambda x : h[x], reverse = True)

جرب هذا الرمز:

def elementFreq(myList):
    #myList is the list of lists
    from collections import Counter
    tmp = []
    for i in myList: tmp += i        
    return(Counter(tmp))

ملاحظة: يجب أن تكون قوائمك نوعا شائعا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top