How to append and uniqify a tuple - python

d1 = ({'x':1, 'y':2}, {'x':3, 'y':4})
d2 = ({'x':1, 'y':2}, {'x':5, 'y':6}, {'x':1, 'y':6, 'z':7})
I have two tuple d1 and d2. I know tuples are immutable. So I have to append another tuple using list. Is there any better solution.
Next question is How to uniqify a tuple on keys say 'x'. if 'x':1 in keys comes twice it is dulicate.
append_tuple = ({'x':1, 'y':2}, {'x':5, 'y':6}, {'x':1, 'y':6, 'z':7}, {'x':1, 'y':2}, {'x':3, 'y':4})
unique_tuple = ({'x':1, 'y':2}, {'x':3, 'y':4}, {'x':5, 'y':6})
Note:
I want to remove the duplicate element from a tuple of dict if key values say 'x' has save value in two dict then those are duplicate element.

There is no better way to extend a tuple. I would say if you are constantly doing this, you need to migrate away from a tuple, or change your design.
Yet again it sounds like you are using the wrong type of collection. But you could remove the duplicated keys from the dictionary using the existing SO answer How to uniqufy the tuple element?

Tuples are generally for data where the number of items is fixed and each place has its own "meaning", so things like sorting, appending, and removing duplicates will never be very natural on tuples and weren't designed to be. If you're stuck with tuples, converting to a list, doing these operations, then converting back is perfectly reasonable.
For appending, you'd do:
d1 += (ITEM,)
and to extend, you'd just do:
d1 += d2
For uniquifying:
unique_list = []
for i1 in append_tuple:
if not any((k,v) in i2.items() for (k,v) in i1.items() for i2 in unique_list):
unique_list.append(i1)
unique_tuple = tuple(unique_list)
It might seem like there's a more concise/elegant solution, but what you are trying to do is fairly specific, and for stuff like this it's better to be explicit and build up the list in a for loop than to try to force it into a comprehension or similar.

Related

Is there a better way to add entries from lists to a dictionary?

As I was studying Python, I came across this task:
Imagine Python did not have built-in support for sets. Show how we
could use dictionaries to represent sets. Write the four set
operations | - ^ & for this new representation of sets.
Below you can see the answer:
First, for the ‘or’ operation, we add entries to the new dictionary
from both input lists:
l1 = [1,2,3,4,5]
l2 = [4,5,6,7,8]
def t_or(l1,l2):
result = {}
for x in l1: result[x] = 0
for x in l2: result[x] = 0
print(result)
So, I'm wondering why have the author used such a strange method to add entries result[x] = 0? Isn't there a better way to do it, maybe using alternatives methods like .add, .insert, etc?
result[key] = value is the way to assign a new pair key:value in a Python dictionary. You don't have to create the entry key first on a Dictionary. If you come from Java, for example, the syntaxis is like:
Map<String, String> result = new HashMap<int, int>();
result.put(1, 0);
As you can see, on Java you are not declaring the key too, the same happens on a lot of languages and that is because of how a dictionary key works.
When you want to retrieve an element from a dictionary, you have to be sure that the key already exists in the dictionary, otherwise it will throw an exception.
The .add or .insert that you have in mind in Python is .append and it is used to add a new element to a list:
my_list = []
my_list.append(0)
So no, there is no a better way or a different way to assign new key:value pairs on a Python dictionary.

Adding two asynchronous lists, into a dictionary

I've always found Dictionaries to be an odd thing in python. I know it is just me i'm sure but I cant work out how to take two lists and add them to the dict. If both lists were mapable it wouldn't be a problem something like dictionary = dict(zip(list1, list2)) would suffice. However, during each run the list1 will always have one item and the list2 could have multiple items or single item that I'd like as values.
How could I approach adding the key and potentially multiple values to it?
After some deliberation, Kasramvd's second option seems to work well for this scenario:
dictionary.setdefault(list1[0], []).append(list2)
Based on your comment all you need is assigning the second list as a value to only item of first list.
d = {}
d[list1[0]] = list2
And if you want to preserve the values for duplicate keys you can use dict.setdefault() in order to create value of list of list for duplicate keys.
d = {}
d.setdefault(list1[0], []).append(list2)

Python Dedup/Merge List of Dicts

Say that I have a list of dicts:
list = [{'name':'john','age':'28','location':'hawaii','gender':'male'},
{'name':'john','age':'32','location':'colorado','gender':'male'},
{'name':'john','age':'32','location':'colorado','gender':'male'},
{'name':'parker','age':'24','location':'new york','gender':'male'}]
In this dict, 'name' can be considered a unique identifier. My goal is to not only dedup this list for identical dicts (ie list[1] and list[2], but to also merge/append differing values for a single 'name' (ie list[0] and list[1/2]. In other words, I want to merge all of the 'name'='john' dicts in my example to a single dict, like so:
dedup_list = [{'name':'john','age':'28; 32','location':'hawaii; colorado','gender':'male'},
{'name':'parker','age':'24','location':'new york','gender':'male'} ]
I have tried thus far to create my second list, dedup_list, and to iterate through the first list. If the 'name' key does not already exist in one of dedup_list's dicts, I will append it. It is the merging part where I am stuck.
for dict in list:
for new_dict in dedup_list:
if dict['name'] in new_dict:
# MERGE OTHER DICT FIELDS HERE
else:
dedup_list.append(dict) # This will create duplicate values as it iterates through each row of the dedup_list. I can throw them in a set later to remove?
My list of dicts will never contain more than 100 items, so an O(n^2) solution is definitely acceptable but not necessarily ideal. This dedup_list will eventually be written to a CSV, so if there is a solution involving that, I am all ears.
Thanks!
well, I was about to craft a solution around defaultdict, but hopefully #hivert posted the best solution I could came with, which is in this answer:
from collections import defaultdict
dicts = [{'a':1, 'b':2, 'c':3},
{'a':1, 'd':2, 'c':'foo'},
{'e':57, 'c':3} ]
super_dict = defaultdict(set) # uses set to avoid duplicates
for d in dicts:
for k, v in d.iteritems():
super_dict[k].add(v)
i.e. I'm voting for closing this question as a dupe of that question.
N.B.: you won't be getting values such as '28; 32', but instead get a set containing [28,32], which then can be processed into a csv file as you wish.
N.B.2: to write the csv file, have a look at the DictWriter class

List Comprehension of Lists Nested in Dictionaries

I have a dictionary where each value is a list, like so:
dictA = {1:['a','b','c'],2:['d','e']}
Unfortunately, I cannot change this structure to get around my problem
I want to gather all of the entries of the lists into one single list, as follows:
['a','b','c','d','e']
Additionally, I want to do this only once within an if-block. Since I only want to do it once, I do not want to store it to an intermediate variable, so naturally, a list comprehension is the way to go. But how? My first guess,
[dictA[key] for key in dictA.keys()]
yields,
[['a','b','c'],['d','e']]
which does not work because
'a' in [['a','b','c'],['d','e']]
yields False. Everything else I've tried has used some sort of illegal syntax.
How might I perform such a comprehension?
Loop over the returned list too (looping directly over a dictionary gives you keys as well):
[value for key in dictA for value in dictA[key]]
or more directly using dictA.itervalues():
[value for lst in dictA.itervalues() for value in lst]
List comprehensions let you nest loops; read the above loops as if they are nested in the same order:
for lst in dictA.itervalues():
for value in lst:
# append value to the output list
Or use itertools.chain.from_iterable():
from itertools import chain
list(chain.from_iterable(dictA.itervalues()))
The latter takes a sequence of sequences and lets you loop over them as if they were one big list. dictA.itervalues() gives you a sequence of lists, and chain() puts them together for list() to iterate over and build one big list out of them.
If all you are doing is testing for membership among all the values, then what you really want is to a simple way to loop over all the values, and testing your value against each until you find a match. The any() function together with a suitable generator expression does just that:
any('a' in lst for lst in dictA.itervalues())
This will return True as soon as any value in dictA has 'a' listed, and stop looping over .itervalues() early.
If you're actually checking for membership (your a in... example), you could rewrite it as:
if any('a' in val for val in dictA.itervalues()):
# do something
This saves having to flatten the list if that's not actually required.
In this particular case, you can just use a nested comprehension:
[value for key in dictA.keys() for value in dictA[key]]
But in general, if you've already figured out how to turn something into a nested list, you can flatten any nested iterable with chain.from_iterable:
itertools.chain.from_iterable(dictA[key] for key in dictA.keys())
This returns an iterator, not a list; if you need a list, just do it explicitly:
list(itertools.chain.from_iterable(dictA[key] for key in dictA.keys()))
As a side note, for key in dictA.keys() does the same thing as for key in dictA, except that in older versions of Python, it will waste time and memory making an extra list of the keys. As the documentation says, iter on a dict is the same as iterkeys.
So, in all of the versions above, it's better to just use in dictA instead.
In simple code just for understanding this might be helpful
ListA=[]
dictA = {1:['a','b','c'],2:['d','e']}
for keys in dictA:
for values in dictA[keys]:
ListA.append(values)
You can do some like ..
output_list = []
[ output_list.extend(x) for x in {1:['a','b','c'],2:['d','e']}.values()]
output_list will be ['a', 'b', 'c', 'd', 'e']

How to declare and add items to an array in Python?

I'm trying to add items to an array in python.
I run
array = {}
Then, I try to add something to this array by doing:
array.append(valueToBeInserted)
There doesn't seem to be a .append method for this. How do I add items to an array?
{} represents an empty dictionary, not an array/list. For lists or arrays, you need [].
To initialize an empty list do this:
my_list = []
or
my_list = list()
To add elements to the list, use append
my_list.append(12)
To extend the list to include the elements from another list use extend
my_list.extend([1,2,3,4])
my_list
--> [12,1,2,3,4]
To remove an element from a list use remove
my_list.remove(2)
Dictionaries represent a collection of key/value pairs also known as an associative array or a map.
To initialize an empty dictionary use {} or dict()
Dictionaries have keys and values
my_dict = {'key':'value', 'another_key' : 0}
To extend a dictionary with the contents of another dictionary you may use the update method
my_dict.update({'third_key' : 1})
To remove a value from a dictionary
del my_dict['key']
If you do it this way:
array = {}
you are making a dictionary, not an array.
If you need an array (which is called a list in python ) you declare it like this:
array = []
Then you can add items like this:
array.append('a')
Arrays (called list in python) use the [] notation. {} is for dict (also called hash tables, associated arrays, etc in other languages) so you won't have 'append' for a dict.
If you actually want an array (list), use:
array = []
array.append(valueToBeInserted)
Just for sake of completion, you can also do this:
array = []
array += [valueToBeInserted]
If it's a list of strings, this will also work:
array += 'string'
In some languages like JAVA you define an array using curly braces as following but in python it has a different meaning:
Java:
int[] myIntArray = {1,2,3};
String[] myStringArray = {"a","b","c"};
However, in Python, curly braces are used to define dictionaries, which needs a key:value assignment as {'a':1, 'b':2}
To actually define an array (which is actually called list in python) you can do:
Python:
mylist = [1,2,3]
or other examples like:
mylist = list()
mylist.append(1)
mylist.append(2)
mylist.append(3)
print(mylist)
>>> [1,2,3]
You can also do:
array = numpy.append(array, value)
Note that the numpy.append() method returns a new object, so if you want to modify your initial array, you have to write: array = ...
Isn't it a good idea to learn how to create an array in the most performant way?
It's really simple to create and insert an values into an array:
my_array = ["B","C","D","E","F"]
But, now we have two ways to insert one more value into this array:
Slow mode:
my_array.insert(0,"A") - moves all values ​​to the right when entering an "A" in the zero position:
"A" --> "B","C","D","E","F"
Fast mode:
my_array.append("A")
Adds the value "A" to the last position of the array, without touching the other positions:
"B","C","D","E","F", "A"
If you need to display the sorted data, do so later when necessary. Use the way that is most useful to you, but it is interesting to understand the performance of each method.
I believe you are all wrong. you need to do:
array = array[] in order to define it, and then:
array.append ["hello"] to add to it.

Categories