Frage

Ich mag mehrere Listen Rang nach ihren Elementen, wie oft sie in jeder Liste erscheinen. Beispiel:

list1 = 1,2,3,4
list2 = 4,5,6,7
list3 = 4,1,8,9

result = 4,1,2,3,4,5,6,7,8 (4 dreimal gezählt, 1 zweimal und den Rest einmal)

Ich habe versucht, das folgend, aber ich brauche etwas intelligenter und etwas, das ich mit jedem ammount von Listen tun können.


 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

Hier ist das Problem ... Ich kann es immer wieder mit a3 tun kann, A4 und A5, aber es ist zu komplex dann, ich brauche eine Funktion für diesen ... Aber ich weiß nicht, wie ... mein Mathe blieb stecken;)

GELöST: vielen Dank für das Gespräch. Als newbee Ich mag dieses System irgendwie: schnell + informativ. Sie hat mir geholfen, alle heraus! Ty

War es hilfreich?

Lösung

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)

Nun wollen wir es verallgemeinern (jede iterable zu nehmen, lösen hashable Anforderung), erlauben Schlüssel und Reverse-Parameter (sortiert übereinstimmen), und benennen Sie auf 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)]

Beispiel:

>>> 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)]

Andere Tipps

Die Kombination von ein paar Ideen, die bereits geschrieben:

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)]

Weitere Informationen:

  1. In Python 2.7 können Sie Counter statt defaultdict(int) verwenden.
  2. Diese Version nimmt eine beliebige Anzahl von Listen als Argument; der führende Stern bedeutet, sie werden alle in ein Tupel verpackt werden. Wenn Sie in einer einzigen Liste enthält alle Ihre Listen übergeben möchten, lassen Sie das führende Sternchen.
  3. Dies bricht, wenn Ihre Listen einen unhashable Typen enthalten.
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)

Versuchen Sie dieses:

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)]

Anwendungsbeispiel:

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

print rank(a,b,c)

Sie können eine beliebige Anzahl von Listen als Eingabe verwenden

Sie können die Anzahl der Auftritte jedes Element zählen (ein Histogramm), dann sortieren, indem sie es:

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)

Versuchen Sie diesen Code ein:

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

Hinweis: Ihre Listen sollten hashable Typ sein

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top