iNoob
iNoob

Reputation: 1395

Dictionary from two lists

I've been looking to create a dictionary from two set lists. I understand how to do this if I want each item in each list to be marked key and value for example:

list_one = ['a', 'b', 'c']
list_two = ['1', '2', '3']
dictionary = dict(zip(list_one, list_two))
print dictionary
{'a': 1, 'b': 2, 'c': 3}

However I'm looking to use all the items in list_two as values for the first item in list_one. This would then hit another loop and item in list_one will change and so will the items in list_two.

Hope this makes sense.

Any ideas would be appreciated.

Code used to create lists

def local_file(domain, user_list):
    cmd = subprocess.check_output(["tasklist", "/V", "/FO", "CSV"])
    tasks = csv.DictReader(cmd.splitlines(), dialect="excel")

    image_name = set()
    users = set()
    for task in tasks:
        if task['User Name'] == 'N/A': continue
        task_domain, task_user = task['User Name'].split('\\')
        if task_user in task['User Name']:
            image_name.add(task['Image Name'])
        else:
            pass
        if domain == task_domain and task_user in user_list:
            users.add(task['User Name'])
    sorted(image_name)
    print "Users found:\n"
    print '\n'.join(users)
    print "\nRuning the following services and applications.\n"
    print '\n'.join(image_name)
    if arguments['--app'] and arguments['--output'] == True:
        keys = users
        key_values = image_name
        dictionary = dict(zip(list_one, list_two))
        print dictionary
    elif arguments['--output'] == True:
        return users
    else:
        pass

Upvotes: 0

Views: 142

Answers (2)

kojiro
kojiro

Reputation: 77127

We don't know what's updating list two. Until we do, we can only guess. Idiomatically, whatever gets the values should be an iterable (so that you can use next).

res = {}
for k in list_one:
  res[k] = next(lists_two)

or

res = {k:next(lists_two) for k in list_one}

if you have Python 2.7 or higher.

For an example that would have the same result as your comment, using grouper from itertools recipes:

from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

lists_two = grouper(range(3*len(list_one)), 3)
res = {k:next(lists_two) for k in list_one}

Upvotes: 0

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250961

I guess you're looking for something like this:

>>> list_one = ['a', 'b', 'c']
>>> list_two = ['1', '2', '3']
>>> {item: list_two[:] for item in list_one}
{'c': ['1', '2', '3'], 'b': ['1', '2', '3'], 'a': ['1', '2', '3']}

For Python 2.6 and earlier:

>>> dict((item, list_two[:]) for item in list_one)
{'c': ['1', '2', '3'], 'b': ['1', '2', '3'], 'a': ['1', '2', '3']}

Note that [:] is required to create a shallow copy of the list, otherwise all values will point to the same list object.

Update:

As per your comment list_two will change during the iteration, here I've used an iterator to get the new value for list_two during the iteration:

>>> out = {}
>>> it = iter([['1', '2', '3'], ['5', '6', '7'], ['8', '9', '10']])
>>> list_two = next(it)  #here `next` can be your own function.
>>> for k in list_one:
        out[k] = list_two
        list_two = next(it)  #update list_two with the new value.

 >>> out
{'c': ['8', '9', '10'], 'b': ['5', '6', '7'], 'a': ['1', '2', '3']}

#or

>>> it = iter([['1', '2', '3'], ['5', '6', '7'], ['8', '9', '10']])
>>> out = {}
>>> for k in list_one:
        list_two = next(it)  #fetch the value of `list_two`
        out[k] = list_two

Upvotes: 1

Related Questions