Given the linear order that is completely represented by a list of tuples of strings, print the order as a list of strings

The specified pairs of form elements [(a,b),...], where (a,b)means a > b, for example:

[('best','better'),('best','good'),('better','good')]

I would like to list the form:

['best','better','good']

This is very difficult for some reason. Any thoughts?

========================== code ========================= ==================================================== ==

I know why this is not working.

def to_rank(raw):

  rank = []

  for u,v in raw:
    if u in rank and v in rank:
      pass

    elif u not in rank and v not in rank:
      rank = insert_front (u,v,rank)
      rank = insert_behind(v,u,rank)

    elif u in rank and v not in rank:
      rank = insert_behind(v,u,rank)

    elif u not in rank and v in rank:
      rank = insert_front(u,v,rank)

  return [[r] for r in rank]

# @Use: insert word u infront of word v in list of words
def insert_front(u,v,words):
  if words == []: return [u]
  else:
    head = words[0]
    tail = words[1:]
    if head == v: return [u] + words
    else        : return ([head] + insert_front(u,v,tail))

# @Use: insert word u behind word v in list of words
def insert_behind(u,v,words):
  words.reverse()
  words = insert_front(u,v,words)
  words.reverse()
  return words

==================== Update ====================

According to many, this is a straightforward topological sorting, I eventually decided to use the code from this source: algocoding.wordpress.com/2015/04/05/topological-sorting-python/

who solved my problem.

def go_topsort(graph):
in_degree = { u : 0 for u in graph }     # determine in-degree 
for u in graph:                          # of each node
    for v in graph[u]:
        in_degree[v] += 1

Q = deque()                 # collect nodes with zero in-degree
for u in in_degree:
    if in_degree[u] == 0:
        Q.appendleft(u)

L = []     # list for order of nodes

while Q:                
    u = Q.pop()          # choose node of zero in-degree
    L.append(u)          # and 'remove' it from graph
    for v in graph[u]:
        in_degree[v] -= 1
        if in_degree[v] == 0:
            Q.appendleft(v)

if len(L) == len(graph):
    return L
else:                    # if there is a cycle,  
    return []      

RockBilly , v < u, (u,v) . "", .

+4
7

, , . , (, wiki I)

+1

, :

>>> import itertools as it
>>> from collections import Counter
>>> ranks = [('best','better'),('best','good'),('better','good')]
>>> c = Counter(x for x, y in ranks)
>>> sorted(set(it.chain(*ranks)), key=c.__getitem__, reverse=True)
['best', 'better', 'good']

, dfs , . , :):

def dfs(graph, start, end):
    stack = [[start]]
    while stack:
        path = stack.pop()
        if path[-1] == end:
            yield path
            continue
        for next_state in graph.get(path[-1], []):
            if next_state in path:
                continue
            stack.append(path+[next_state])

def paths(ranks):
    graph = {}
    for n, m in ranks:
        graph.setdefault(n,[]).append(m)
    for start, end in it.product(set(it.chain(*ranks)), repeat=2):
        yield from dfs(graph, start, end)

>>> ranks = [('black', 'dark'), ('black', 'dim'), ('black', 'gloomy'), ('dark', 'gloomy'), ('dim', 'dark'), ('dim', 'gloomy')]
>>> max(paths(ranks), key=len)
['black', 'dim', 'dark', 'gloomy']
>>> ranks = [('a','c'), ('b','a'),('b','c'), ('d','a'), ('d','b'), ('d','c')]
>>> max(paths(ranks), key=len)
['d', 'b', 'a', 'c']
+2

, . , , , , .

, , . , , .

from copy import copy

def find_lowest_item(s):
    #Iterate over set of all items
    for item in set([item for sublist in s for item in sublist]):
        #If an item does not appear at the start of any tuple, return it
        if item not in [x[0] for x in s]:
            return item

def sort_by_comparison(s):
    final_list = []
    #Make a copy so we don't mutate original list
    new_s = copy(s)
    #Get the set of all items
    item_set = set([item for sublist in s for item in sublist])
    for i in range(len(item_set)):
        lowest = find_lowest_item(new_s)
        if lowest is not None:
            final_list.insert(0, lowest)
        #For the highest ranked item, we just compare our current 
        #ranked list with the full set of items
        else:
            final_list.insert(0,set(item_set).difference(set(final_list)).pop())
        #Update list of ranking tuples to remove processed items
        new_s = [x for x in new_s if lowest not in x]
    return final_list

list_to_compare = [('black', 'dark'), ('black', 'dim'), ('black', 'gloomy'), ('dark', 'gloomy'), ('dim', 'dark'), ('dim', 'gloomy')]
sort_by_comparison(list_to_compare)

[ "", "", "", "" )

list2 = [('best','better'),('best','good'),('better','good')]
sort_by_comparison(list2)

['best', 'better', 'good']

list3 = [('best','better'),('better','good')]
sort_by_comparison(list3)

['best', 'better', 'good']

+1

. ( Python 2) cmp, functools.cmp_to_key key, Python 3 :

import functools

def sortByRankings(rankings):
    def cmp(x,y):
        if x == y:
            return 0
        elif (x,y) in rankings:
            return -1
        else:
            return 1

    items = list({x for y in rankings for x in y})
    items.sort(key = functools.cmp_to_key(cmp))
    return items

:

ranks = [('a','c'), ('b','a'),('b','c'), ('d','a'), ('d','b'), ('d','c')]
print(sortByRankings(ranks)) #prints ['d', 'b', 'a', 'c']

, rankings . , , , .

+1

. , python .

def order(a):
newlist=[]
for listp in range(len(a)):
    for subp in range(len(a[listp])):
        if a[listp][subp] not in newlist:
            newlist.append(a[listp][subp])
newlist.sort()
return newlist 
s =  [('best', 'better'), ('best', 'good'), ('better', 'good')]
print(order(s))
0

, , @Rockybilly. , .

def remove_duplicates(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

i = [(5,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
i = remove_duplicates(list(x for s in i for x in s))
print(i)  # prints [5, 2, 1, 3, 4]

j = [('excellent','good'),('excellent','great'),('great','good')]
j = remove_duplicates(list(x for s in j for x in s))
print(j)  # prints ['excellent', 'good', 'great']

. : ?

remove_duplicates() . postoverflow post.

-1

, ( ), .

from collections import defaultdict
lst = [('best','better'),('best','good'),('better','good')]

d = defaultdict(int)

for tup in lst:
    d[tup[0]] += 1
    d[tup[1]] += 0 # To create it in defaultdict

print sorted(d, key = lambda x: d[x], reverse=True)
# ['best', 'better', 'good']

, , .

Edit: I think the OP has a specific input type. Always have the number of combinations nCr (n, 2). This makes this the right decision. No need to complain about cases of edges that I already knew when posting an answer (and mentioned this).

-3
source

Source: https://habr.com/ru/post/1663478/


All Articles