This question already has answers here:
What is the purpose of the single underscore "_" variable in Python?
(5 answers)
Closed 8 months ago.
Reading through Peter Norvig's Solving Every Sudoku Puzzle essay, I've encountered a few Python idioms that I've never seen before.
I'm aware that a function can return a tuple/list of values, in which case you can assign multiple variables to the results, such as
def f():
return 1,2
a, b = f()
But what is the meaning of each of the following?
d2, = values[s] ## values[s] is a string and at this point len(values[s]) is 1
If len(values[s]) == 1, then how is this statement different than d2 = values[s]?
Another question about using an underscore in the assignment here:
_,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
Does the underscore have the effect of basically discarding the first value returned in the list?
d2, = values[s] is just like a,b=f(), except for unpacking 1 element tuples.
>>> T=(1,)
>>> a=T
>>> a
(1,)
>>> b,=T
>>> b
1
>>>
a is tuple, b is an integer.
_ is like any other variable name but usually it means "I don't care about this variable".
The second question: it is "value unpacking". When a function returns a tuple, you can unpack its elements.
>>> x=("v1", "v2")
>>> a,b = x
>>> print a,b
v1 v2
The _ in the Python shell also refers to the value of the last operation. Hence
>>> 1
1
>>> _
1
The commas refer to tuple unpacking. What happens is that the return value is a tuple, and so it is unpacked into the variables separated by commas, in the order of the tuple's elements.
You can use the trailing comma in a tuple like this:
>>> (2,)*2
(2, 2)
>>> (2)*2
4
Related
This question already has answers here:
How do I call a function twice or more times consecutively?
(9 answers)
Closed 3 years ago.
My aim is to have many inputs from a user stored in a disordered manner. So, I decided to use a set. The code I have so far is:
a = input()
b = input()
c = input()
d = input()
all = a, b, c, d
print(set(all))
However, I do not want to repeat input() several times like above. Is there a way to achieve this?
If all you want is a set you do not need a, b, c, d.
all = set() #or all = {*(),}
for _ in range(4):
all.add(input())
print(all)
Or,
all = {input() for _ in range(4)}
This is considering you take the inputs in new line. Otherwise, if the input are comma-separated for example:
all = set(input().split(','))
print(all)
or
all = {*input().split(',')}
print(all)
In case you need both a, b, c, d and all the inputs, you could do:
>>> all = a, b, c, d = {*input().split(',')}
# example
>>> all = a, b, c, d = {1, 2, 3, 4}
>>> all
{1, 2, 3, 4}
>>> a
1
>>> b
2
As pointed out by #Tomerikoo all(iterable) is a built-in function avoid naming your variables same as python builints or keywords.
Another point, if in case you have already done so, in order to get the default behavior of all, you could do:
>>> import builtins
>>> all = builtins.all
# Or, more conveniently, as pointed out by #Martijn Pieters
>>> del all
* is used for iterable unpacking
_ is used for don't care or throwaway or anonymous variable,
as we do not need the variable in the loop. More on this
here.
{*()} is just a fancy way of creating empty sets as python does not have empty set literals. It is recommended to use set()
You could put your calls to input() in a comprehension:
set(input() for i in range(4))
You could use a for loop:
all = set()
for _ in range(4):
all.add(int(input())
print(all)
Don't forget that input gives you a string, so you should convert it to int or any type if needed excplicitly.
"_" in the for loop means that this variable is not important. But you can put whatever name you like.
I have a few variables in python3:
a = 1
b = [2,3,4]
c = 5
I want to get a tuple which is from above variables, like: (1,2,3,4,5)
what is the easiest way to do that in python3?
Creating a tuple in Python is as simple as putting the stuff you need in a tuple in parentheses:
my_tuple = (1, 2, 3)
a = 1
b = 2
c = 3
another_tuple = (a, b, c) # also works with variables, or anything else with a value
And if what you want in the tuple is in something else that can be unpacked, like a list or a tuple itself, you can use the unpacking operator * to unpack it into the new tuple:
a = 1
b = [2,3,4]
c = 5
my_tuple = (a, *b, c)
Not your question, but note that you can also get stuff from a tuple without using the * operator, as it's implied in an assignment statement:
x, _, z = my_tuple # continued from before
In this example, what was in a (1) is now also in x and what was in c also in z. What was in b and in the second position of the tuple gets discards (that's what the underscore _ here means, "don't care".)
You use the unpack operator in cases where you explicitly need to unpack and you're constructing some new variable, or need the elements of the tuple separately where they could also be used as a tuple. For example, when calling a function:
a_tuple = ('Hi there', 'John')
def greeting(phrase='Hello', name='world'):
print(f'{phrase}, {name}!')
greeting(*a_tuple)
In this example, calling greeting as greeting(a_tuple) would give you the very nasty result of ('Hi there', 'John'), world!, clearly not what you want, but you can still use the tuple with the unpack operator.
And the other obvious example is one like the one solving OP's question.
Simply create a new tuple as shown below.
newTuple=(a, *b, c)
Note: *b unpacks list b into variables and add each variable to indexes of newTuple
One of the ways is shown below
from functools import reduce
import operator
# create a bunch of lists, reduce them to one list and finally convert to tuple
result = tuple(reduce(operator.add, ([a], b, [c])))
print(result)
This is the most pythonic solution:
a = 1
b = [2,3,4]
c = 5
res = a,*b,c
# output: (1,2,3,4,5)
Note: To create the new tuple, round brackets are not necessary in Python3
This question already has answers here:
Why does adding a trailing comma after an expression create a tuple?
(6 answers)
Closed 3 years ago.
In the below code if I don't use comma then only one 0 gets printed while if I use comma 0 gets printed five times, why? Is it something to do with the immutable trait of the tuple?
food = (0,) * 5 # comma used
print (*food)
Output: 0 0 0 0 0
food = (0) * 5 # comma not used
print (*food)
Output:0
It's a syntax thing. What defines the tuple is not the parenthesis, but the presence of the comma:
Parenthesis around a single scalar expression are used to define order of evaluation: (1 + 2) * 3
A sequence of expressions separated by commas defines a tuple: 1, 2, 3.
This sequence can then be parenthesized if it needs to be embedded in some other expression: (1, 2, 3) * 5 is "the tuple (1,2,3) repeated five times".
Specifically for a single-item tuple, the syntax requires a trailing comma to differentiate it from a parenthesized expression: 0, is a tuple containing only the element 0; Usually you'd immediately want to parenthesize this expression if you wanted to embed it in a larger expression, e.g. (0,) * 5 ("the tuple consisting of zero, multiplied five times"). Whereas 0 and (0) both mean "the integer zero" (parenthesized in the latter form).
>>> type( (0, ) )
tuple
>>> type ( (0) )
int
So (0) * 5 is "the integer 0 multiplied by 5", giving you 0. There's no tuple involved at any point because the syntax you used does not define a tuple.
Because:
>>> (0)
0
>>>
So 0 * 5 is 0, while:
>>> (0,)
(0,)
>>>
Keeps it's type of a tuple.
Tuples and Sequences From documentation a tuple with one item is constructed by following a value with a comma
A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For Example
>>> t=('hello')
>>> t
'hello'
>>> type(t)
<class 'str'>
>>> t1=('hello',)
>>> t1
('hello',)
>>> type(t1)
<class 'tuple'>
>>>
According to: [Python 3.Docs]: Built-in Types - class tuple([iterable]) (emphasis is mine):
Using a trailing comma for a singleton tuple: a, or (a,)
food definition (note that things would be the same without parentheses):
In the 1st case, it's a tuple (as (0,) is a tuple)
In the the 2nd case, it's a plain int (0 * 5)
>>> v0 = (0,)
>>> v1 = (0)
>>>
>>> v0, type(v0)
((0,), <class 'tuple'>)
>>> v1, type(v1)
(0, <class 'int'>)
>>>
>>> v0 * 5
(0, 0, 0, 0, 0)
>>> v1 * 5
0
Are you absolutely sure that print(*food) works (as you claim it does) in the 2nd case?
Let's say I have a string
str1 = "TN 81 NZ 0025"
two = first2(str1)
print(two) # -> TN
How do I get the first two letters of this string? I need the first2 function for this.
It is as simple as string[:2]. A function can be easily written to do it, if you need.
Even this, is as simple as
def first2(s):
return s[:2]
In general, you can get the characters of a string from i until j with string[i:j].
string[:2] is shorthand for string[0:2]. This works for lists as well.
Learn about Python's slice notation at the official tutorial
t = "your string"
Play with the first N characters of a string with
def firstN(s, n=2):
return s[:n]
which is by default equivalent to
t[:2]
Heres what the simple function would look like:
def firstTwo(string):
return string[:2]
In python strings are list of characters, but they are not explicitly list type, just list-like (i.e. it can be treated like a list). More formally, they're known as sequence (see http://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange):
>>> a = 'foo bar'
>>> isinstance(a, list)
False
>>> isinstance(a, str)
True
Since strings are sequence, you can use slicing to access parts of the list, denoted by list[start_index:end_index] see Explain Python's slice notation . For example:
>>> a = [1,2,3,4]
>>> a[0]
1 # first element, NOT a sequence.
>>> a[0:1]
[1] # a slice from first to second, a list, i.e. a sequence.
>>> a[0:2]
[1, 2]
>>> a[:2]
[1, 2]
>>> x = "foo bar"
>>> x[0:2]
'fo'
>>> x[:2]
'fo'
When undefined, the slice notation takes the starting position as the 0, and end position as len(sequence).
In the olden C days, it's an array of characters, the whole issue of dynamic vs static list sounds like legend now, see Python List vs. Array - when to use?
All previous examples will raise an exception in case your string is not long enough.
Another approach is to use
'yourstring'.ljust(100)[:100].strip().
This will give you first 100 chars.
You might get a shorter string in case your string last chars are spaces.
For completeness: Instead of using def you could give a name to a lambda function:
first2 = lambda s: s[:2]
Used a loop to add a bunch of elements to a list with
mylist = []
for x in otherlist:
mylist.append(x[0:5])
But instead of the expected result ['x1','x2',...], I got: [u'x1', u'x2',...]. Where did the u's come from and why? Also is there a better way to loop through the other list, inserting the first six characters of each element into a new list?
The u means unicode, you probably will not need to worry about it
mylist.extend(x[:5] for x in otherlist)
The u means unicode. It's Python's internal string representation (from version ... ?).
Most times you don't need to worry about it. (Until you do.)
The answers above me already answered the "u" part - that the string is encoded in Unicode. About whether there's a better way to extract the first 6 letters from the items in a list:
>>> a = ["abcdefgh", "012345678"]
>>> b = map(lambda n: n[0:5], a);
>>> for x in b:
print(x)
abcde
01234
So, map applies a function (lambda n: n[0:5]) to each element of a and returns a new list with the results of the function for every element. More precisely, in Python 3, it returns an iterator, so the function gets called only as many times as needed (i.e. if your list has 5000 items, but you only pull 10 from the result b, lambda n: n[0:5] gets called only 10 times). In Python2, you need to use itertools.imap instead.
>>> a = [1, 2, 3]
>>> def plusone(x):
print("called with {}".format(x))
return x + 1
>>> b = map(plusone, a)
>>> print("first item: {}".format(b.__next__()))
called with 1
first item: 2
Of course, you can apply the function "eagerly" to every element by calling list(b), which will give you a normal list with the function applied to each element on creation.
>>> b = map(plusone, a)
>>> list(b)
called with 1
called with 2
called with 3
[2, 3, 4]