¿Cómo hacer coincidir y asignar datos de la manera pythonic?

I have a list (mysql table) of People and their titles as shown in the table below. I also have a list of titles and their categories. How do I assign their categories to the person? The problem arises when there are multiple titles for a person. What is the pythonic way of mapping the title to the category and assigning it to the person?

Tabla de personas

Name   Title
--------------------
John D CEO, COO, CTO 
Mary J COO, MD
Tim  C Dev Ops, Director

Title Category table

Title      Executive IT Other
-----------------------------
CEO        1
COO        1
CTO        1          1
MD         1
Dev Ops               1
Director                 1

Salida deseada :

Name   Title             Executive  IT  Other
---------------------------------------------
John D CEO, COO, CTO     1          1
Mary J COO, MD           1 
Tim  C Dev Ops, Director            1   1

preguntado el 03 de mayo de 12 a las 20:05

It would help to see what your intended output should look like. -

How are your people stored? A class, a string? This question is far too vague. -

Also where is the list of titles and categories? -

@ThinkCode check out my solution. -

4 Respuestas

name_title = (("John D",("CEO","COO","CTO")),
              ("Mary J",("COO","MD")),
              ("Tim C",("Dev Ops","Director")))
title_cat = {"CEO": set(["Executive"]),
             "COO": set(["Executive"]),
             "CTO": set(["Executive"]),
             "MD": set(["Executive"]),
             "Dev Ops": set(["IT"]),
             "Director": set(["Other"])}

name_cat = [(name, reduce(lambda x,y:x|y, [title_cat[title]for title in titles])) for name,titles in name_title]

It would be nice if there was a union which behaved like sum on sets.

contestado el 03 de mayo de 12 a las 20:05

A title can have 2 categories or more, in this case CTO has 2 categories, IT and Executive? This is a small sample, I have few thousand contacts! Thanks.... - pensar código

Si tu puedes hacer "CTO":set(["Executive","IT"]) - Keith Randall

Thank you, will give it a shot! - pensar código

Keith, would you change anything if you have half a million contacts with titles and about 20000 different titles to map. How to scale the solution in that case? Iterators? Thank you! - pensar código

Probablemente quieras algo como title_cat[title] if title in title_cat else set(). Or use a defaultdict instead of a regular dictionary. - Keith Randall

people=['john','Mary','Tim']
Title=[['CEO','COO','CTO'],['COO','MD'],['DevOps','Director']]
title_des={'CEO':'Executive','COO':'Executive','CTO':'Executive',
           'MD':'Executive','DevOps':'IT','Director':'Others'
           }
people_des={}

for i,x in enumerate(people):
    people_des[x]={}
    for y in Title[i]:
        if title_des[y] not in people_des[x]:
             people_des[x][title_des[y]]=[y]
        else:     
             people_des[x][title_des[y]].append(y) 
print(people_des)            

salida:

{'Tim': {'IT': ['DevOps'], 'Others': ['Director']}, 'john': {'Executive': ['CEO', 'COO', 'CTO']}, 'Mary': {'Executive': ['COO', 'MD']}}

contestado el 03 de mayo de 12 a las 20:05

Thank you, I will check it out! - pensar código

Start by arranging your input data in a dictionary-of-lists form:

>>> name_to_titles = {
        'John D': ['CEO', 'COO', 'CTO'],
        'Mary J': ['COO', 'MD'],
        'Tim C': ['Dev Ops', 'Director']
}

Then loop over the input dictionary to create the reverse mapping:

>>> title_to_names = {}
>>> for name, titles in name_to_titles.items():
        for title in titles:
            title_to_names.setdefault(title, []).append(name)

>>> import pprint
>>> pprint.pprint(title_to_names)
{'CEO': ['John D'],
 'COO': ['John D', 'Mary J'],
 'CTO': ['John D'],
 'Dev Ops': ['Tim C'],
 'Director': ['Tim C'],
 'MD': ['Mary J']}

contestado el 03 de mayo de 12 a las 21:05

I propose this if you mean you have the string:

s = '''Name   Title
--------------------
John D CEO, COO, CTO
Mary J COO, MD
Tim  C Dev Ops, Director

Title      Executive IT Other
-----------------------------
CEO        1
COO        1
CTO        1
MD         1
Dev Ops               1
Director                 1
'''

lines = s.split('\n')
it = iter(lines)

for line in it:
    if line.startswith('Name'):
        break

next(it) # '--------------------'

for line in it:
    if not line:
        break
    split = line.split()
    titles = split[2:]
    name = split[:2]
    print ' '.join(name), titles

# John D ['CEO,', 'COO,', 'CTO']
# Mary J ['COO,', 'MD']
# Tim C ['Dev', 'Ops,', 'Director']

contestado el 03 de mayo de 12 a las 20:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.