dictionary update sequence element error - python

I have several dictionary files, I want this code to open each file and add it to a set, for later comparison and matching. Basically I have a different list of all permutations of all possible characters and I need to know if permutation is in dictionary. But when I try to make a set with all dictionary lines I get this error:
choices = ['s','m','o','k','e','j','a','c','k']
def parsed(choices):
mySet = {}
for item in choices:
filename = self.location + "/dicts/%s.txt" % (item)
mySet.update(open(filename).read().splitlines())
return mySet
I get this error
error: dictionary update sequence element #0 has length 4; 2 is required
Furthermore, I'd like to ask if there's a possible comparison method between two sets of data (9 character permutations, and 9 dictionary files list) that runs in less than 1 minute.
I understand that there are already questions regarding this error, but frankly I'm a beginner and I don't understand how those relate to my code, or how to fix it.

If you write:
mySet = {}
mySet is not a set, but a dictionary (yeah that is confusing). For instance:
>>> type({})
<class 'dict'>
In order to construct an empty set, you should use:
mySet = set()
A set indeed has a function update that takes as input an iterable of elements that are all added to the set. A dictionary on the other hand requires an iterable of tuples (or a dictionary, etc.)

Related

How to find maximum element from a list and its index?

I have a list with ordered dictionaries. These ordered dictionaries have different sizes and can also have the same size(for example, 10 dictionaries can have the length of 30 and 20 dictionaries can have the length of 32). I want to find the maximum number of items a dictionary from the list has. I have tried this, which gets me the correct maximum length:
maximum_len= max(len(dictionary_item) for dictionary_item in item_list)
But how can I find the dictionary fields for which the maximum_len is given? Say that the maximum_len is 30, I want to also have the dictionary with the 30 keys printed. It can be any dictionary with the size 30, not a specific one. I just need the keys of that dictionary.
Well you can always use filter:
output_dics=filter((lambda x: len(x)==maximum_len),item_list)
then you have all the dictionarys that satisfies the condition , pick a random one or the first one
Don't know if this is the easiest or most elegant way to do it but you could just write a simple function that returns 2 values, the max_length you already calculated but also the dict that you can get via the .index method and the max_length of the object you were searching for.
im talking about something like this:
def get_max(list_of_dict):
plot = []
for dict_index, dictionary in enumerate(list_of_dict):
plot.append(len(dictionary))
return max(plot), list_of_dict[plot.index(max(plot))]
maximum_len, max_dict = get_max(test)
tested it, works for my case, although i have just made myself a testlist with just 5 dicts of different length.
EDIT:
changed variable "dict" to "dictionary" to prevent it shadowing from outer scope.

How to manipulate string items in a 3d list in python? (without numpy)

I have a 3d list 6 items long and 6 items wide, which is a list of lists of a list of strings.
lst = [ [['A'],['A'],['B'],['B'],['A'],['A']],
[['B'],['B'],['A'],['A'],['B'],['B']],
[['A'],['A'],['B'],['B'],['A'],['A']],
[['B'],['B'],['A'],['A'],['B'],['B']],
[['A'],['A'],['B'],['B'],['A'],['A']],
[['B'],['B'],['A'],['A'],['B'],['B']],
]
I want to move the strings into other locations on the list, but I know I'm not using the right code:
lst.insert([1][0][0], 'A')
gives me a TypeError: 'int' object is not subscriptable
I know how to add items by doing this:
lst2 = lst[0][0]
lst2.append('A')
(adds another 'A' string to the first item)
I want to perform various actions on the lowest list like:
add/remove strings to that list,
check how many string items are in that list
move 'A' or 'B' strings to different locations so that they have multiple strings.
Check to see what the first string is in the list is
I am very new to programming and I am just starting to understand how to use 2d lists.
How do I accomplish this without any additional modules or libraries?
First of all, let me clarify this line:
lst.insert([1][0][0], 'A')
The insert method expects an int argument for the index. If you want to insert an element in a multidimensional list it should be done as:
lst[1][0].insert(0, 'A')
After all, it is a list of list (of lists). Only if you look at an inner index (defined by 2 coordinates), will you get a simple list (of strings in this case). You can then insert a string element to this simple list, by calling the insert() method.
check how many string items are in that list
count = 0
for d2 in lst: #d2 is a 2d list (an element of a 3d list)
for d1 in d2: # d1 - 1 dimensional
count += len(d1)
Here, I have gone through each of the lowermost-level (simple) lists using a nested loop, counted how many elements are there in each and added them up.
move 'A' or 'B' strings to different locations so that they have multiple strings.
Say I want to move the element from [3][2][0] to [1][2][1]. I would insert it in the new position and then delete from the old.
element = lst[3][2][0] # the task can be accomplished without using another variable, but this is for better understanding
lst[1][2].insert(1, element) # inserting
lst[3][2].pop(0) # deleting
The element could even be moved to a position like [1][2]. So there would be one string along with the other 'sub-lists'
Check to see what the first string is in the list is
Do you mean lst[0][0][0].

Cannot extend a list and take set() in a single step without Non-Iterable error

I'm trying to manage a list of unique items that may (or may not) get additions with each iteration of a loop. Maybe they are just integers produced by doSomething(someData).
So with each iteration I call doSomething and want to add my results to a growing list...
uniqs = []
for md in mydata:
newOnes = doSomething(md) # returns a list eg [3,2,3]
uniqs = list(set(uniqs.extend(newOnes))) # keep only uniquely new items
But It appears i can't do the extend and the set at the same time without an error
TypeError: 'NoneType' object is not iterable
I can do it in two steps,
uniqs = []
for md in mydata:
newOnes = doSomething(md) # returns a list eg [3,2,3]
uniqs.extend(newOnes) # extend the list will all new items
uniqs = list(set(uniqs)) # keep only unique items
but I'd have thought that line would be okay, as the extend() would occur before the set() would be applied. Not sure why it isn't.
Can someone clarify why that is?
-Ross
If you are happy for uniqs to be a set rather than a list, you can use update to iterate over the list and add any elements that do not already exist:
uniqs = set()
for md in mydata:
newOnes = doSomething(md)
uniqs.update(newOnes)
If required, you can convert it to a list at the end with uniqs = list(uniqs). The ordering will be undefined, but as you are already using a set as an intermediate in your calculation, this is already the case.
You could perhaps write the above as a one-liner using functools.reduce:
functools.reduce(set.union, (set(doSomething(md)) for md in mydata))
although the explicit loop is probably more readable.

Python : initializing list and dictionary

I am new to Python. while initializing a list
mylist = list()
mylist[0]="hello"
gives error .It only works
mylist.append("hello")
but if i do same with dictionary
mydict ={}
mydict["one"]="hello"
it works.
why i dont need to do
mydict['one'].append('hello')
why things are different for different structures.
If you update a dict like this:
d['c'] = 3
... there is no need for d['a'] and d['b'] (or any item at all, for that matter) to be present in that dict. The key of a dictionary item does not imply any specific structural properties of your dict object.
However, if you want to update a list like this:
l[5] = 'a'
... the indexes 0 through 5 absolutely must exist. The index not only serves as a handle for an element in the list, but also has structural properties. If l[5] does exist, you can be absolutely sure that indexes 0 through 4 do as well. And you need that certainty.
Imagine you could do l[5] = 'a' on an empty list. What would len(l) return? 1? 6?
Both cases would cause this to fail:
for i in range(len(l)):
print(l[i])
One can argue that l[<index>] = 'a' could implicitly append that value if index-1 already exists or if the list is empty and the desired index is 0. In order for this to reliably work, you would need to ensure that index-1 exists before adding values like this, while, when using append(), you are guaranteed that your value will be added to the list (except for potential edge cases like memory starvation).
If you add an element to a dictionary you connect to a key.
In your case you connect the element 'hello' to your key 'one'
To add an element to a list you will have to use the function list.append.
You use list[x] to get the element at position x.

How can I find the intersection of a list and a nested list?

I have a list of fruits:
fruits = ["apple","banana"]
I also have a nested list of baskets, in which each list contains a string (the name of the basket) and a list of fruits.
baskets = [["basket1",["apple","banana","pear","strawberry"]],["basket2",["strawberry","pear","peach"]],["basket3",["peach","apple","banana"]]]
I would like to know which baskets contain every fruits in the list fruits: the result I expect is a list with two elements, "basket1" and "basket3".
I figured that intersections would the cleanest way of achieving that, and I tried the following:
myset = set(fruits).intersection(*map(set, set(baskets)))
But I'm getting a TypeError "unhashable type: 'list'". I understand that I can't map lists, but I thought that using the function "set" on both lists would convert them to sets... is there any other way I can find the intersection of a list and a list of lists?
You can loop over baskets and check if the fruits set is a subset of fruits in current basket, if yes store current basket's name.
>>> fruits = {"apple", "banana"} #notice the {}, or `set(["apple","banana"])` in Python 2.6 or earlier
>>> [b for b, f in baskets if fruits.issubset(f)]
['basket1', 'basket3']
You can't hash sets any more than you can hash lists. They both have the same problem: because they're mutable, a value can change its contents, making any set that contains it as a member or any dictionary that contains it as a key suddenly invalid.
You can hash the immutable equivalents of both, tuple and frozenset.
Meanwhile, your immediate problem is ironically created by your attempt to solve this problem. Break this line down into pieces:
myset = set(fruits).intersection(*map(set, set(baskets)))
The first piece is this:
baskets_set = set(baskets)
You've got a list of lists. You, set(baskets) is trying to make a set of lists. Which you can't do, because lists aren't hashable.
If you just removed that, and used map(set, baskets), you would then have an iterator of sets, which is a perfectly valid thing.
Of course as soon as you try to iterate it, it will try to make a set out of the first element of baskets, which is a list, so you'll run into the error again.
Plus, even if you solve this, the logic still doesn't make any sense. What's the intersection of a set of, say, 3 strings with a set of, say, 3 (frozen)sets of strings? It's empty. The two sets don't have any elements in common. The fact that some elements of the second one may contain elements of the first doesn't mean that the second one itself contains any elements of the first.
You could do it this way using your approach:
fruits = ["apple","banana"]
baskets = [["basket1",["apple","banana","pear","strawberry"]],
["basket2",["strawberry","pear","peach"]],
["basket3",["peach","apple","banana"]]]
fruitset = set(fruits)
res = set(b for b, s in ((b, set(c)) for b, c in baskets) if s & fruitset)
print res # --> set(['basket1', 'basket3'])

Categories