Back to the list of similar authors

I am trying to write a function that will return a list of elements from a key from a key (if that makes sense). For example, there is a dictionary of authors and similar authors.

authors = {
    'Ray Bradbury': ['Harlan Ellison', 'Robert Heinlein', 'Isaac Asimov', 'Arthur Clarke'],
    'Harlan Ellison': ['Neil Stephenson', 'Kurt Vonnegut', 'Richard Morgan', 'Douglas Adams'],
    'Kurt Vonnegut': ['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer'],
    'Thomas Pynchon': ['Isaac Asimov', 'Jorges Borges', 'Robert Heinlein'],
    'Isaac Asimov': ['Stephen Baxter', 'Ray Bradbury', 'Arthur Clarke', 'Kurt Vonnegut', 'Neil Stephenson'],
    'Douglas Adams': ['Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']
}

And the function that I came up with is this:

def get_similar(author_list, author):
    for item in author_list[author]:
        return author_list[author]

Returns only the elements for the first key. I would like it to return all such authors, for example:

get_similar(authors, 'Harlan Ellison')

['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 
 'Jeff Vandemeer','Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']

, (), , , . : , , . - , , , , , ,

, , ( , sort ). , !

+4
8

, , . , .

authors = {'Ray Bradbury': ['Harlan Ellison', 'Robert Heinlein', 'Isaac Asimov', 'Arthur Clarke'], 'Harlan Ellison': ['Neil Stephenson', 'Kurt Vonnegut', 'Richard Morgan', 'Douglas Adams'], 'Kurt Vonnegut': ['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer'], 'Thomas Pynchon': ['Isaac Asimov', 'Jorges Borges', 'Robert Heinlein'], 'Isaac Asimov': ['Stephen Baxter', 'Ray Bradbury', 'Arthur Clarke', 'Kurt  Vonnegut', 'Neil Stephenson'], 'Douglas Adams': ['Terry  Pratchett', 'Chris Moore', 'Kurt Vonnegut']}


def get_similar(authors, author):
    retVal = []
    for k, v in authors.items():
        if k == author:
            for value in v:
                retVal.append(value)
                if value in authors:
                    for v2 in authors[value]:
                       retVal.append(v2)
return sorted(retVal)

get_similar (, "Harlan Ellison" ) [' ',  ' ',  ' ',   " ",   " ",   " ",   " ",   " ",   " ",   " ",   " ",   " " ]

, , .

+1

, , , , , for:

def get_similar(author_list, author):
    similar_authors = []
    for item in author_list[author]:
        if item in author_list:
            similar_authors.extend(author_list[item])
    return similar_authors

, if, , item , (: "Neil Stephenson" , ).

:

( )

- generator. , , yield , :

def get_similar2(author_list, author):
    for item in author_list[author]:
        if item in author_list:
            for other_author in author_list[item]:
                yield other_author 

, python 3.3+, , yield from, get_similar2:

def get_similar3(author_list, author):
    for item in author_list[author]:
        if item in author_list:
            yield from author_list[item]

/ ( , ):

print(get_similar(authors, 'Harlan Ellison'))
['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer', 'Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']

print(list(get_similar2(authors, 'Harlan Ellison')))
['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer', 'Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']

print(list(get_similar3(authors, 'Harlan Ellison')))
['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer', 'Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']
+1

:

def get_similar(author_list, author):
    similar = set(author_list.get(author, []))
    similar.update(*[author_list.get(item, []) for item in similar])
    return sorted(similar)

get_similar(authors, 'Harlan Ellison')

:

['Chris Moore', 'Douglas Adams', 'Jeff Vandemeer', 'Kurt Vonnegut',
 'Neil Stephenson', 'Richard Morgan', 'Terry Pratchett', 'Tom Robbins']
+1

, , for - , , , . , , , ... - :

def get_similar(authors, author):
    return [a for x in authors.pop(author, []) for a in [x] + get_similar(authors, x)]

get_similar(authors, 'Harlan Ellison')

# ['Neil Stephenson', 'Kurt Vonnegut', 'Terry Pratchett', 'Tom Robbins', 'Douglas Adams',
#  'Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut', 'Neil Stephenson', 'Jeff Vandemeer',
#  'Richard Morgan', 'Douglas Adams']

, , , , , (- ), :

def get_similar(authors, author):
    return sorted(set([a for x in authors.pop(author, []) for a in [x] + get_similar(authors, x)]))

# ['Chris Moore', 'Douglas Adams', 'Jeff Vandemeer', 'Kurt Vonnegut', 'Neil Stephenson', 'Richard Morgan', 'Terry Pratchett', 'Tom Robbins']

, , , , , authors , get_similar(authors.copy(), author).

+1

, . , , ( ) .

authors = {'Ray Bradbury': ['Harlan Ellison', 'Robert Heinlein', 'Isaac Asimov', 'Arthur Clarke'], 'Harlan Ellison': ['Neil Stephenson', 
           'Kurt Vonnegut', 'Richard Morgan', 'Douglas Adams'], 'Kurt Vonnegut': ['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 
           'Neil Stephenson', 'Jeff Vandemeer'], 'Thomas Pynchon': ['Isaac Asimov', 'Jorges Borges', 'Robert Heinlein'], 'Isaac Asimov': 
           ['Stephen Baxter', 'Ray Bradbury', 'Arthur Clarke', 'Kurt Vonnegut', 'Neil Stephenson'], 'Douglas Adams': ['Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']}

def get_similar(author_list, author, currentList=[]):
    for similar in author_list[author]:
        if similar not in currentList:
            currentList.append(similar)
            if similar in authors:
                get_similar(author_list, author, currentList)
    return sorted(currentList)

print(get_similar(authors, "Harlan Ellison"))

:

['Douglas Adams', 'Kurt Vonnegut', 'Neil Stephenson', 'Richard Morgan']
0

, , , ,

def get_similar(author_list, author):
     return sorted(author_list[author])
0

+ itertools.chain

from itertools import chain

def get_similar(author_list, author):
     return sorted(set(chain(*[v for k,v in authors.items() if k in authors[author]])))

get_similar(authors, 'Harlan Ellison')
#['Chris Moore', 'Douglas Adams', 'Jeff Vandemeer', 'Kurt Vonnegut', 'Neil Stephenson', 'Terry Pratchett', 'Tom Robbins']
0

author , list. list comprehension:

def get_similar(author_list, author):
    # Lists of similar authors
    similar = [author_list[auth] for auth in author_list[author] if auth in author_list]

    # Merge the lists and sort the authors. Do not include parameter author
    return sorted(auth for sub in similar for auth in sub if auth != author)



authors = {
    'Ray Bradbury': ['Harlan Ellison', 'Robert Heinlein', 'Isaac Asimov', 'Arthur Clarke'],
    'Harlan Ellison': ['Neil Stephenson', 'Kurt Vonnegut', 'Richard Morgan', 'Douglas Adams'],
    'Kurt Vonnegut': ['Terry Pratchett', 'Tom Robbins', 'Douglas Adams', 'Neil Stephenson', 'Jeff Vandemeer'],
    'Thomas Pynchon': ['Isaac Asimov', 'Jorges Borges', 'Robert Heinlein'],
    'Isaac Asimov': ['Stephen Baxter', 'Ray Bradbury', 'Arthur Clarke', 'Kurt Vonnegut', 'Neil Stephenson'],
    'Douglas Adams': ['Terry Pratchett', 'Chris Moore', 'Kurt Vonnegut']
}


>>> get_similar(authors, 'Harlan Ellison')
['Chris Moore', 'Douglas Adams', 'Jeff Vandemeer', 'Kurt Vonnegut', 'Neil Stephenson', 'Terry Pratchett', 'Terry Pratchett', 'Tom Robbins']

>>> get_similar(authors, 'Ray Bradbury')  # There 'Ray Bradbury' in the values of 'Isaac Asimov'
['Arthur Clarke', 'Douglas Adams', 'Kurt Vonnegut', 'Kurt Vonnegut', 'Neil Stephenson', 'Neil Stephenson', 'Richard Morgan', 'Stephen Baxter']
0

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


All Articles