Implement a group_by_owners dictionary

Viewed 17205

I made a successful attempt on the TestDome.com Fileowners problem and wanted to see if anyone had suggestions to simplify my answer. The online IDE uses Python 3.5.1. If you are trying to do the problem yourself and are just looking for an answer, here's one. I am by know means a Python expert so this took me quite a while to produce with lots of tinkering. Any comments at all would be helpful even if its about syntax or general cleanliness. THANKS!

Implement a group_by_owners function that:

Accepts a dictionary containing the file owner name for each file name. Returns a dictionary containing a list of file names for each owner name, in any order. For example, for dictionary {'Input.txt': 'Randy', 'Code.py': 'Stan', 'Output.txt': 'Randy'} the group_by_owners function should return {'Randy': ['Input.txt', 'Output.txt'], 'Stan': ['Code.py']}.

class FileOwners:

@staticmethod
def group_by_owners(files):
    val = (list(files.values()))                    #get values from dict
    val = set(val)                                  #make values a set to remove duplicates
    val = list(val)                                 #make set a list so we can work with it
    keyst = (list(files.keys()))                    #get keys from dict
    result = {}                                     #creat empty dict for output
    for i in range(len(val)):                       #loop over values(owners)
        for j in range(len(keyst)):                 #loop over keys(files)
            if val[i]==list(files.values())[j]:     #boolean to pick out files for current owner loop
                dummylist = [keyst[j]]              #make string pulled from dict a list so we can add it to the output in the correct format
                if val[i] in result:                #if the owner is already in the output add the new file to the existing dictionary entry
                    result[val[i]].append(keyst[j]) #add the new file
                else:                               #if the owner is NOT already in the output make a new entry 
                    result[val[i]] = dummylist      #make a new entry
    return result

files = {
'Input.txt': 'Randy',
'Code.py': 'Stan',
'Output.txt': 'Randy'
}

print(FileOwners.group_by_owners(files))

Output:

{'Stan': ['Code.py'], 'Randy': ['Output.txt', 'Input.txt']} 
13 Answers

I personally found the upvoted answer hard to understand and some others a bit bulky. Here is my version:

def group_by_owners(files):

ownerdict = {}

for key, value in files.items():
    if value in ownerdict:
        ownerdict[value].append(key)
    else:
        ownerdict[value] = [key]
return ownerdict


files = {
    'Input.txt': 'Randy',
    'Code.py': 'Stan',
    'Output.txt': 'Randy'
}
print(group_by_owners(files))

This worked for me. I believe this would be more efficient and simpler one.

# Input dictionary.
files = {
        'Input.txt': 'Randy',
        'Code.py': 'Stan',
        'Output.txt': 'Randy'
    }   
# Function to group the files.   
def group_by_owners(files):

    # Dictionary object to hold the result.
    result = {}

    for key, value in files.items():

        if value not in result.keys():

            # Insert the values into the resulting dictionary
            # by interchanging the key, values.
            result[value] = [key]
        else:

            # Append the othet file name if the owner is same.
            result[value].append(key)

    return result

print(group_by_owners(files))

Here is the output:

{'Randy': ['Input.txt', 'Output.txt'], 'Stan': ['Code.py']}

I just started learning and I am a noob at python too but used 2.7. So spare me the parentheses for prints.

I like your idea of dummy list and append. Something similar but may be a little cleaner:

files = {
    'Input.txt': 'Randy',
    'Code.py': 'Stan',
    'Output.txt': 'Randy'
}
owners=[]
filenames=files.keys()
for key in files:
    if files[key] not in owners:
        owners.append(files[key])
print owners
print filenames

result={}
for i in owners:
    resultvalues=[]
    for key in files:
        if files[key]==i: 
            resultvalues.append(key)
            print resultvalues
            result[i]=resultvalues
print result

here I mentioning easily understandable solution,

owner = []
for i in dict1.keys():
if j not in owner:
    owner.append(j)
results = {}
for i in owner:
    result = []
    for j in dict1.keys():
        if dict1.get(j) == i:
            result.append(j)
        results[i] = result
print results
def group_by_owners(files):    
    values = []
    dic = {}

    for k,v in files.items():
        values.append(v)

    s_values = set(values)
    l_values = list(s_values)

    for i in l_values:
        keys=[] 
        for k,v in files.items():
            if v == i:
             keys.append(k)
        dic[i]=keys            

    return dic

You all seems better I took 3.5 hours to get answer with lot of try and error as am new to python and weak in thinking focused, thanks to @zwer for teaching something new.

dic={'apple':['green','red'], 'power': ['voltage'],'banana': ['green','red'],'current':['voltage'],'grass':['green'],'tiger':['lion']}


i = 0
adic = {}
while i < len(dic):
    key = list(dic)[i]
    for key2 in list(dic):
        if key2 != key:
            j = 0
            while j < len(dic[key]):
                if dic[key][j] in dic[key2]:
                    color = dic[key][j]
                    if dic[key][j] in adic:
                        if key not in adic[color]:
                            adic[dic[key][j]].append(key)

                    else:
                        mdic = {dic[key][j]: [key]}
                        adic.update(mdic)
                else:
                    if dic[key][j] not in adic:
                        mdic = {dic[key][j]: [key]}
                        adic.update(mdic)
                j = j + 1
    i = i + 1
print(adic)
class FileOwners:
    def group_by_owners(files):
    temp=[]

    for i in files:
        if files[i] not in temp:
            temp.append (files[i])
        result={}

    for j in temp:
        temp1=[]
        for i in files:
            if files[i]==j: 
                temp1.append(i)
                result[j]=temp1
    return (result)

files = {'Input.txt': 'Randy',
        'Code.py': 'Stan',
        'Output.txt': 'Randy'}

print(FileOwners.group_by_owners(files))

You have to iterate Dictionary into Dictionary and compare values and append keys in a new list. Take output in a new Dictionary.

class FileOwners:

    @staticmethod

    def group_by_owners(files):
        new_dic = {}

        for key,val in files.items():
            key_list = []
            for k,v in files.items():

                if v == val:
                    #print(v)
                    key_list.append(k)
                    new_dic[v]= key_list

        return new_dic
        #print(new_dic)
files = {
    'Input.txt': 'Randy',
    'Code.py': 'Stan',
    'Output.txt': 'Randy'
}
print(FileOwners.group_by_owners(files))

I made a dict of owners and their associated list of filenames. To do that i firstly created the dictionary with the values of the passed dictionary files as keys and empty list as values. Then looped through files and appended the empty list with the keys of files

def group_by_owners(files):
    return_dict = {}
    owner_files = files.keys()
    for f in owner_files:
        return_dict[files[f]] = []
    for f, n in files.items():
        return_dict[n].append(f)
    return return_dict

I started learning Python yesterday and came across this question on testdome. Here's my answer :

def group_by_owners(files):
    f = files.values()
    s = set(f)
    newdict={}
    fileOwners = list(s)
    for owner in fileOwners:
        l=[]
        for file in files:
            if owner == files[file]:
                l.append(file)
        newdict[owner]=l
    return newdict


files = {
    'Input.txt': 'Randy',
    'Code.py': 'Stan',
    'Output.txt': 'Randy'
}   
print(group_by_owners(files))
  1. This is some complex code to understand.
  2. but is one of the solutions.

        files={
          'input.txt':'randy',
          'output.txt':'randy',
          'code.py':'stan'
          }
      k=files.keys()
      newfiles={value:key for key,value in files.items()}
      emptylist=[]
      for key in k:
          if key not in newfiles.values():
              missfile=key
              valuetoadd=files[missfile]
      emptylist.append(newfiles[valuetoadd])
      emptylist.append(missfile)
      newfiles[valuetoadd]=emptylist
      print(newfiles)
    

Here is my answer with defaultdict:

    from collections import defaultdict
    
    d = defaultdict(list)

    def group_by_owners(files):
        for k,v in files.items():
            d[v].append(k)
        return dict(d.items())

    if __name__ == "__main__":    
        files = {
            'Input.txt': 'Randy',
            'Code.py': 'Stan',
            'Output.txt': 'Randy'
        }   
        print(group_by_owners(files))
Related