I was learning Python 3 on SoloLearn, and this question came up:
What is the result of this code?
primes = {1: 2, 2: 3, 4: 7, 7:17}
print(primes[primes[4]])
The result is : 17
print(primes[4])
gives : 7
I know it a simple concept, but I never needed such a concept...
Thanks
Well,
prime[4]
evaluates to
7
because 7 is the value corresponding to the key 4.
Breaking this down
prime[prime[4]]
becomes
prime[7]
which is
17
since, once again, 17 is the value corresponding to the key 7 of your dictionary.
primes = {1: 2, 2: 3, 4: 7, 7:17}
Where primes is a dict with key-value paired elements in it.
print(primes[4]) # 7
Means, print the value of dict with key 4, i.e. 7:
print(primes[primes[4]]) # 17
Where, it means print the value of dict with the key primes[4] which is 7, i.e. it becomes primes[7] which results in 17
Related
This question already has answers here:
Scope of python variable in for loop
(10 answers)
Closed 9 years ago.
I am trying to do something as simple as changing the varible in which I am iterating over (i) but I am getting different behaviours in both Python and C.
In Python,
for i in range(10):
print i,
if i == 2:
i = 4;
I get 0 1 2 3 4 5 6 7 8 9, but the equivalent in C:
int i;
for (i = 0; i < 10; i++) {
printf("%d", i);
if (i == 2)
i = 4;
}
I get 01256789 (note that numbers 3 and 4 don't appear, as expected).
What's happening here?
Python has a few nice things happening in the background of for loops.
For example:
for i in range(10):
will constantly set i to be the next element in the range 0-10 no matter what.
If you want to do the equivalent in python you would do:
i = 0
while i < 10:
print(i)
if i == 2:
i = 4
else: # these line are
i += 1 # the correct way
i += 1 # note that this is wrong if you want 1,2,4,5,6,7,8,9
If you are trying to convert it to C then you have to remember that the i++ in the for loop will always add to the i.
The function range() creates a list.
For example, range(10) will create the following list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
When you say for i in range(10), first off all the list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] will be generated, and then i will be assigned all the values from that list, in order.
It doesn't matter if you change the value of i because on the next iteration it will be assigned the next element from the list.
It C/C++ on the other hand, at the end of each iteration the value of i is incremented and then compared to the maximum allowed value (in this case 9) and if it is greater, then the loop ends.
When you call range(10) you create an iteratable list [0,1,2,3,4,5,6,7,8,9].
And the for loop just pick up one number after the other from the list at each turn, whether or not you haved changed the value of i.
Python gives you the elements in range(10), one after another. C repeatedly increments a variable.
Both of them don't really care what else you do with the variable inside the loop, but since the two language constructs do slightly different things, the outcome is different in some cases.
You can not do this by using range function.
you have to do it by using while loop only because for loop uses range function and in range function variable will get incremented by its internal method no matter what you specify in the loop it will get incremented by range list only.
for i in range(10):
... print i
... if i == 2:
... i = 4
... else:
... i += 1
...
0
1
2
3
4
5
6
7
8
9
An interesting example is here....
for i in range(10):
... print i
... i = i + 10
... print i
...
this will print...
0
10
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
It's because when you use the range() function in python. Your variable i will be go through the value in range. For example,
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
However, the C language that you have written is just using the normally condition to change the value of i. There is no function involved.
So I am trying to solve a problem, where a user will input a number and you have to find the next number that has all unique digits. For example:
Input: 1987, Output:
2013
Input:
999, Output:
1023
The way I thought of tackling this question was to go through every number after the number given by the user until I find a number that has all unique digits.
My question is that is there a way to check through every whole number greater than a number given. Until I find a specific one. So this is without a list or range. Just want to check every number until I find a specific type. Would I have to use a for loop or something similar.
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
num = 5
given = 10
new = [i for i in arr if i >= num and i <= given]
i dont know if this is what you wanted you did not specify it.
The beginner way - while True loop
i = int(input()) + 1
while True:
if digits_are_unique(i): # Undefined
break
i += 1
print(i)
The pro way - itertools.count()
import itertools
i = int(input()) + 1
for i in itertools.count(i):
if digits_are_unique(i): # Undefined
break
print(i)
Assignment expression - new in Python 3.8
Right now Python 3.8 is in beta and I don't have the interpreter to test this with, but it should work.
i = int(input()) + 1
while i := i + 1:
if digits_are_unique(i): # Undefined
break
print(i)
input={1:5,2:8,9:3,11:4,18:3,21:4,3:8}
and I would like to do the group by operation and perform the sum operation on
the value in those dictionary ..
like grp_1=1,2,3 ; grp_2=9,11,18 ; grp_3= 21
and output should like as below
grp_1= 21 (5+8+8 dict values)
grp_2= 10 (3+4+3 dict values)
grp_3= 4
Please suggest us the simple way..
From the example I guess you want to form constant size groups across the dict ordered by keys. In this case you can first sort the keys, get the values, generate chunks of the desired size and sum each of them. I could not find tool in the standard library which is able to yield chunks from a iterator, hence I use here the more_itertools module as suggested here.
import more_itertools as mit
d = {1: 5, 2: 8, 9: 3, 11: 4, 18: 3, 21: 4, 3: 8}
group_sums = list(map(
sum,
mit.more.chunked(
(d[k] for k in sorted(d.keys())),
3
)
))
I would do as follows:
import pandas as pd
# initial data
sr = pd.Series({1:5,2:8,9:3,11:4,18:3,21:4,3:8})
groups = [[1,2,3],[9,11,18],[21]]
# we will save the sums in this list
finalsum = []
for i in groups:
finalsum.append(sr[sr.index.isin(i)].sum())
So the sum of groups[0] would be finalsum[0] and so on.
This question already has answers here:
Why is the order in dictionaries and sets arbitrary?
(5 answers)
Closed 7 years ago.
I have a question about dictionary properties in python when the keys are number.
in my case when I print a dictionary with number keys the result of print will be sorted by keys but in the other case (keys are string) dictionary is unordered. I want to know about this rule in dictionaries.
l = {"one" : "1", "two" : "2", "three" : "3"}
print(l)
l = {1: "one", 2: "two", 3: "three", 4: "four", 5: "five"}
print(l)
l = {2: "two", 3: "three", 4: "four", 1: "one", 5: "five"}
print(l)
result:
{'three': '3', 'two': '2', 'one': '1'}
{1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'}
{1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'}
Python use hash table for storing the dictionaries so there is no ordered in dictionaries or other objects that use hash function.
But about the indices of items in a hash object, python calculate the indices based on following code within hashtable.c:
key_hash = ht->hash_func(key);
index = key_hash & (ht->num_buckets - 1);
So as the hash value of integers is the integer itself the index is based on the number (ht->num_buckets - 1 is a constant) so the index calculated by Bitwise-and between (ht->num_buckets - 1) and the number.
consider the following example with set that use hash-table :
>>> set([0,1919,2000,3,45,33,333,5])
set([0, 33, 3, 5, 45, 333, 2000, 1919])
For number 33 we have :
33 & (ht->num_buckets - 1) = 1
That actually it's :
'0b100001' & '0b111'= '0b1' # 1 the index of 33
Note in this case (ht->num_buckets - 1) is 8-1=7 or 0b111.
And for 1919 :
'0b11101111111' & '0b111' = '0b111' # 7 the index of 1919
And for 333 :
'0b101001101' & '0b111' = '0b101' # 5 the index of 333
For more details about python hash function its good to read the following quotes from python source code :
Major subtleties ahead: Most hash schemes depend on having a "good" hash
function, in the sense of simulating randomness. Python doesn't: its most
important hash functions (for strings and ints) are very regular in common
cases:
>>> map(hash, (0, 1, 2, 3))
[0, 1, 2, 3]
>>> map(hash, ("namea", "nameb", "namec", "named"))
[-1658398457, -1658398460, -1658398459, -1658398462]
This isn't necessarily bad! To the contrary, in a table of size 2**i, taking
the low-order i bits as the initial table index is extremely fast, and there
are no collisions at all for dicts indexed by a contiguous range of ints.
The same is approximately true when keys are "consecutive" strings. So this
gives better-than-random behavior in common cases, and that's very desirable.
OTOH, when collisions occur, the tendency to fill contiguous slices of the
hash table makes a good collision resolution strategy crucial. Taking only
the last i bits of the hash code is also vulnerable: for example, consider
the list [i << 16 for i in range(20000)] as a set of keys. Since ints are their own hash codes, and this fits in a dict of size 2**15, the last 15 bits of every hash code are all 0: they all map to the same table index.
But catering to unusual cases should not slow the usual ones, so we just take
the last i bits anyway. It's up to collision resolution to do the rest. If
we usually find the key we're looking for on the first try (and, it turns
out, we usually do -- the table load factor is kept under 2/3, so the odds
are solidly in our favor), then it makes best sense to keep the initial index
computation dirt cheap.
Im aware that this may come up as a duplicate but so far I haven't found (or should that be understood) an answer to what Im looking for.
I have a list of strings and want to convert each one into a variable name which I then assign something to. I understand that I may need a dict for this but I am unfamiliar with them as I am relatively new to python and all the examples I have seen so far deal with values whilst I'm trying something different.
Im after something like:
list = ['spam', 'eggs', 'ham']
for i in range(len(list)):
list[i] = rat.readColumn(ratDataset, list[i])
where the first list[i] is a variable name and not a string. The second list[i] is a string (and for context is the name of a column Im reading from a raster attribute table (rat))
Essentially I want each string within the list to be set as a variable name.
The idea behind this is that I can create a loop without having to write out the line for each variable I want, with matching rat column name (the string). Maybe there is a beer way of doing this than I am suggesting?
Try the following:
lst = ['spam', 'eggs', 'ham']
d = {} # empty dictionary
for name in lst:
d[name] = rat.readColumn(ratDataset, name)
Do not use list for your identifiers as it is a type identifier and you would mask its existence. The for loop can iterate directly for the elements inside -- no need to construct index and use it aganist the list. The d['spam'] will be one of your variables.
Although, it is also possible to create the real variable names like spam, eggs, ham, you would not probably do that as the effect would be useless.
Here comes a simple dictionary use :
variables = ['spam', 'eggs', 'ham']
data = {}
datum = 0
for variable in variables:
data[variable] = datum
datum+=1
print(data)
print("value : ",data[variables[2]])
It gives as result :
{'eggs': 1, 'ham': 2, 'spam': 0}
value : 2
NB : don't use list as a variable name, list is a type identifier that you can use to transform an object into a list if possible (list("abc")==['a', 'b', 'c']) and you are overriding it with your value list right now.
one way is setting the variable name as a string and changing a part or all of it via format() method and then using the string as a varibale via vars()[STRING]
import numpy as np
X1= np.arange(1,10)
y1=[i**2 for i in X1]
X2= np.arange(-5,5)
y2=[i**2 for i in X2]
for i in range(1,3):
X = 'X{}'.format(i)
y = 'y{}'.format(i)
print('X_{}'.format(i) , vars()[X])
print('y_{}'.format(i) , vars()[y])
Output:
X_1 [1 2 3 4 5 6 7 8 9]
y_1 [1, 4, 9, 16, 25, 36, 49, 64, 81]
X_2 [-5 -4 -3 -2 -1 0 1 2 3 4]
y_2 [25, 16, 9, 4, 1, 0, 1, 4, 9, 16]