Python Dictionary print value - python

I'm new to programming and I don't understand what happens. Can someone explain what's going on?
>>> primes = {1: 2, 2: 3, 4: 7, 7: 17}
>>> primes[4]
7
>>> primes[primes[4]]
17
Why does primes[primes[4]] result in 17?

Given the dictionary primes = {1: 2, 2: 3, 4: 7, 7: 17}, primes[4] results in 7.
When evaluating the expression primes[primes[4]], Python has to evaluate primes[4] first, which, as we have seen, is 7.
So primes[primes[4]] is equivalent to primes[7].
I hope you can see that, given the above dictionary, primes[7] results in 17.

To start, the primes variable is a Python dictionary. So let's start by looking at an example:
A dictionary in Python defines key-value pairs. For example, say we have an "ages" dictionary:
ages = {
"James": 20,
"Mike": 13
}
With this data structure, if I wanted to get James' age, I'd say ages['james'] and this value would be an integer, 20.
Well, the same applies to your structure here, except instead of strings for the keys, you have integers. So let's take a look:
primes = {
1: 2,
2: 3,
4: 7,
7: 17
}
If we want to get the 17, we'd go ahead and say primes[7], as the integer 7 is referring to the number 17.

Related

Need to repeat the same loop within each loop an unknown number of times in python

I am new to programming and really don't know how to express my problem, so here is the code:
mapping_dict = {
0: [1, 2, 3, 4, 5, 6],
1: [7, 8, 9],
2: [10, 11, 12],
3: [],
4: [],
5: [],
6: [],
7: [13, 14],
8: [],
9: [],
10: [],
11: [],
12: [],
13: [],
14: []
}
proper_id_list = []
The keys and values in the mapping_dict may be strings too. I need something like this:
proper_id_list = [0,1,7,13,14,8,9,2,10,11,12,3,4,5,6]
Whats going on here is that each list must be appended right after their keys.
So far, the code I could come up with, is as follows:
for a in mapping_dict[0]:
proper_id_list.append(a)
for a in mapping_dict[0]:
proper_id_list.append(a)
for a in mapping_dict[0]:
proper_id_list.append(a) # ... this will keep repeating, God knows how many times
I have hard coded these loops a 20 times and they work but I know this is poor design, restricted to 20 levels and the top level key in the mapping_dict must be a 0.
I hope this makes sense. Please help!
You actually only need a single loop. Start with the lowest key, sort the keys, find them in the list, and insert their respective values.
proper_id = [min(mapping_dict)]
for k in sorted(mapping_dict):
i = proper_id.index(k)
proper_id[i+1:i+1] = mapping_dict[k]
print(proper_id)
# -> [0, 1, 7, 13, 14, 8, 9, 2, 10, 11, 12, 3, 4, 5, 6]
However, based on the comments about depth-first search, I might be missing the point. This might not generalize, or might be very slow for large datasets since it's O(n**2).

Function returning a dictionary with string lengths (keys) and number of occurrence (values) from a list

I am trying to write a function that takes a list of strings and returns a dictionary where the keys represent a length and the values represent how many strings have that length in the list. This is what I have written and my output:
def length_counts(stringList):
stringDict = {}
for value in stringList:
stringDict[len(value)] = stringList.count(value)
return stringDict
#test
sa_countries = ["Brazil", "Venezuela", "Argentina", "Ecuador", "Bolivia", "Peru"]
print(length_counts(sa_countries))
Output:
{6: 1, 9: 1, 7: 1, 4: 1}
Correct output should be:
{6: 1, 9: 2, 7: 2, 4: 1}
Which says there is 1 string with 6 letters, 2 strings with 9 letters, 2 strings with 7 letters, and 1 string with 4 letters.
count will give you the number of occurences of that particular element. So the count of Venezuela will give you the number of Venezuela in the list, not the number of 9 letter words. Try something like this.
sa_countries = ["Brazil", "Venezuela", "Argentina", "Ecuador", "Bolivia", "Peru"]
dict = {}
for country in sa_countries:
if (len(country) in dict):
dict[len(country)] += 1
else:
dict[len(country)] = 1
print(dict)
You can use collections.defaultdict to accumulate string length counts.
from collections import defaultdict
def length_counts(countries):
result = defaultdict(int)
for country in countries:
result[len(country)] += 1
return result
Example
>>> length_counts(sa_countries)
defaultdict(<class 'int'>, {6: 1, 9: 2, 7: 2, 4: 1})
You are rewriting your values.
First you do you stringList.count('Venezuela') which is 1. Then you do stringList.count('Argentina') which is also 1. So you get value 1 for they key of 9, twice.
What I would do is first convert the initial list into a list containing the lengths.
sa_countries = ["Brazil", "Venezuela", "Argentina", "Ecuador", "Bolivia", "Peru"]
sa_countries_lens = [len(s) for s in sa_countries]
That is [6, 9, 9, 7, 7, 4].
Now I would do a count:
from collections import Counter
Counter(sa_countries_lens)
The result is
Counter({6: 1, 9: 2, 7: 2, 4: 1})
Counter is basically a dict and you can do a dict with an increment and a key check, but Counter is nicer, part of the standard library and pretty widespread.
One possible approach is to use collections.Counter; counting is what Counter is for:
from collections import Counter
sa_countries = ["Brazil", "Venezuela", "Argentina", "Ecuador", "Bolivia", "Peru"]
result = Counter(map(len, sa_countries))
print(result)
Output
Counter({9: 2, 7: 2, 6: 1, 4: 1})
From the documentation:
A Counter is a dict subclass for counting hashable objects. It is a
collection where elements are stored as dictionary keys and their
counts are stored as dictionary values. Counts are allowed to be any
integer value including zero or negative counts. The Counter class is
similar to bags or multisets in other languages.

Find every element's first index in a list

Here is a list a=[1,1,1,2,4,2,4,32,1,4,35,23,24,23]
I do this in python:
unique_number=list(set(a))
ans=map(lambda x:a.index(x),unique_number)
output:
<map at 0x2b98b307828>
I want to know what's wrong with my code and find an more efficient way to achieve this.
This code would work as you expected in Python 2. In Python 3, map returns an iterator. You could, e.g., convert it to a list:
>>> ans=map(lambda x:a.index(x),unique_number)
>>> list(ans)
[7, 0, 3, 10, 4, 11, 12]
You can avoid keep re-indexing and building a set first - simply build a dict iterating over a backwards as the dictionary will only keep the last value for a key (in this case - the earliest appearing index), eg:
a=[1,1,1,2,4,2,4,32,1,4,35,23,24,23]
first_index = {v:len(a) - k for k,v in enumerate(reversed(a), 1)}
# {1: 0, 2: 3, 4: 4, 23: 11, 24: 12, 32: 7, 35: 10}
This way you're only scanning the sequence once.
Try this:
for value in map(lambda x:a.index(x),unique_number):
print(value)
or append this:
for var in ans:
print(var)

Dictionary. Create a dictionary that maps the first n counting numbers to their squares

for n in raage(n):
if n==0:
pass
else:
squares={i:i*i for i in xrange(n)}
dict[n]=squares
Here is a question: Create a dictionary that maps the first n counting numbers to their squares. Associate the dictionary with the variable squares.
What is wrong with my code?
>> squares={i:i*i for i in xrange(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
Is all you really need. It's called a dictionary comprehension and it's a sugar syntax for a for loop.
As for your code, you didn't spell range correctly in line 1, or do you have a generator named raage. You also shouldn't pass n into your first line then reassign n to your temp line in the for loop. for not_n in range(n) is how you should do it. Also what if you only give n=0 then squares isn't assign when you get out of the for loop. Also don't use dict as a variable name since it's a keyword in Python.
The biggest problem with your code is that your not really answering the question. The question asks you to find the squares of the first n numbers, and map those numbers to the squares. Instead, your code finds the squares for each number from 0 to n every loop.
But rather than of writing a normal for-loop, You can greatly simplify your code by using a dictionary comprehension:
>>> def map_nums_to_squares(n):
return {i: i * i for i in range(n + 1)}
>>> map_nums_to_squares(2)
{0: 0, 1: 1, 2: 4}
>>> map_nums_to_squares(5)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
>>> map_nums_to_squares(10)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100}
>>>
Here's what I did for that question:
squares={}
m=n
t=1
while m!=0:
squares[m]=m*m
t+=1
m-=1
I used a different variable than n to keep track of how many times the loop needs to run because they do not want you to change the value of n for some reason.

Python: returning the average between two values in a dictionary

I have this function:
def find_nearest(array,value):
idx = (np.abs(array-value)).argmin()
return array[idx]
def df_to_count_dict(df):
count_dict = Counter(df.values)
holder = []
for i in range(1,max(list(count_dict.keys()))):
if i in count_dict.keys(): continue
holder.append(i)
for i in holder:
j = find_nearest(np.array(list(count_dict.keys())),i)
count_dict.update({i:count_dict[j]})
return count_dict
What it does is it takes a data series and uses the Counter function from collection to return back a dictionary. It also replaces values which are not in the dictionary with the closest value.
Now, I want to amend this function to return the same object, the count_dict but replace values not in the keys of the dictionary with the average between what it the missing value is between.
This is best explained by an example:
Take
test = pd.Series([1,2,3,3,7,7,7,8])
Without the function above we get:
Counter(test.values)
Out[459]: Counter({1: 1, 2: 1, 3: 2, 7: 3, 8: 1})
Using the function we get
df_to_count_dict(test)
Out[458]: Counter({1: 1, 2: 1, 3: 2, 4: 2, 5: 2, 6: 2, 7: 3, 8: 1})
As you can see it has added keys 4,5,6 with values 2 as 2 is the value of the closest key (the closest key is 3).
What I have it to return is the AVERAGE between the value of lower closest key and the upper closest key, so the upper closest key is 3, which has value 2, and the upper closest key is 7, which has value 3, so I want the final product to look something like:
df_to_count_dict(test)
Out[458]: Counter({1: 1, 2: 1, 3: 2, 4: 2.5, 5: 2.5, 6: 2.5, 7: 3, 8: 1})
I hope someone can help
This look a lot like school work. So you should figure it out your self. But here is a hint. The query you are being asked to develop is finding the mean between the predecessor's count and the successor's count. The predessor is the largest key smaller or equal to the input and the successor is the smallest key larger than the input.
If you need O(log(n))-complexity then you might look at binary search trees bintrees is a good package https://pypi.python.org/pypi/bintrees/2.0.4.

Categories

Resources