This question already has answers here:
Why does adding a trailing comma after an expression create a tuple?
(6 answers)
Closed 6 months ago.
I had introduced a bug in a script of mine by putting a comma after a function call. Here I will illustrate with a silly example:
def uppered(my_string):
return my_string.upper()
foo = uppered("foo")
print(foo)
This returns, as expected, a string:
FOO
However, if I change the script so that I call the function with a comma appended after the function call, like this:
foo = uppered("foo"),
Then I get a tuple back (!):
('FOO',)
This seems so weird to me - I would have expected the interpreter to return a SyntaxError (as it does if I have two commas instead of one). Can someone please enlighten me what the logic is here and where to find more information on this behavior. My google-fu let me down on this very specific detail.
Because you have created a tuple.
foo = uppered("foo"),
Is equivalent to:
foo = (uppered("foo"),)
Which creates a single-elemnt tuple, obviously equivalent to
foo = ('FOO',)
Tuples in Python can be written as:
my_tuple = ()
or:
my_tuple = (1, 2)
or:
my_tuple = 1, 2
Don't believe me? Well:
>>> my_tuple = 1,
>>> my_tuple
(1,)
Well, it's how Python syntax works. A single comma after a value will turn create a tuple with this value as the first and only element. See answers for this question for a broader discussion.
Imagine there is an omitted pair of parentheses:
foo = (uppered("foo"),)
Why so? It to write like this:
stuff = foo(), bar(), baz()
# More code here
for thing in stuff:
You could've used a pair of parentheses (and you do need them in other languages), but aesthetics of Python require syntax to be as short and clear as possible. Commas are necessary as separators, but parentheses really aren't. Everything between the beginning side of expression and the end of the line (or :, or closing parentheses/brackets in case of generators or comprehensions) is to be elements of the created tuple. For one element tuple, this syntax should be read as "a tuple of this thing and nothing more", because there is nothing between comma and end of the line.
You can use .join() function. It returns string concatenated with
elements of tuple.
g = tuple('FOO')
k = ''
K = k.join(g)
print(K)
print(type(K))
FOO
class 'str'
Related
Why does adding a trailing comma after an expression create a tuple with the expression's value? E.g. in this code:
>>> abc = 'mystring',
>>> print(abc)
('mystring',)
Why is the printed output ('mystring',), and not just mystring?
It is the commas, not the parentheses, which are significant. The Python tutorial says:
A tuple consists of a number of values separated by commas
Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.
See the Python Tutorial section on Tuples and Sequences
Because this is the only way to write a tuple literal with one element. For list literals, the necessary brackets make the syntax unique, but because parantheses can also denote grouping, enclosing an expression in parentheses doesn't turn it into a tuple: you need a different syntactic element, in this case the comma.
Make sure to read this great answer by Ben James.
Tuples are not indicated by the parentheses. Any expression can be enclosed in parentheses, this is nothing special to tuples. It just happens that it is almost always necessary to use parentheses because it would otherwise be ambiguous, which is why the __str__ and __repr__ methods on a tuple will show them.
For instance:
abc = ('my', 'string')
abc = 'my', 'string'
What about single element tuples?
abc = ('mystring',)
abc = 'mystring',
So in effect what you were doing was to create a single element tuple as opposed to a string.
The documentation clearly says:
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
Unpacking multi-element tuple:
a, b = (12, 14)
print(type(a))
Output:
int
Unpacking single-element tuple:
a, = (12, )
print(type(a))
Output:
int
Otherwise:
a = (12,)
print(type(a))
Output:
tuple
In the question's example, you assigned the variable 'abc' to a Tuple with a length of 1.
You can do multiple assignments with this similar syntax:
x,y = 20,50
Also note that the print statement has a special understanding for ending a print statement with a comma; This tells print to omit the trailing newline.
print 'hello',
print 'world'
result:
hello world
I was somewhat confused about the application of the comma, as you also apply a comma to make a list instead of tuple, but with a different variable assignment.
Hereby, a simple example that I made of how to create a tuple or a list.
abc = 1,2,3 # prints a tuple: (1, 2, 3)
*abc, = 1,2,3 # prints a list: [1, 2, 3]
Why does adding a trailing comma after an expression create a tuple with the expression's value? E.g. in this code:
>>> abc = 'mystring',
>>> print(abc)
('mystring',)
Why is the printed output ('mystring',), and not just mystring?
It is the commas, not the parentheses, which are significant. The Python tutorial says:
A tuple consists of a number of values separated by commas
Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.
See the Python Tutorial section on Tuples and Sequences
Because this is the only way to write a tuple literal with one element. For list literals, the necessary brackets make the syntax unique, but because parantheses can also denote grouping, enclosing an expression in parentheses doesn't turn it into a tuple: you need a different syntactic element, in this case the comma.
Make sure to read this great answer by Ben James.
Tuples are not indicated by the parentheses. Any expression can be enclosed in parentheses, this is nothing special to tuples. It just happens that it is almost always necessary to use parentheses because it would otherwise be ambiguous, which is why the __str__ and __repr__ methods on a tuple will show them.
For instance:
abc = ('my', 'string')
abc = 'my', 'string'
What about single element tuples?
abc = ('mystring',)
abc = 'mystring',
So in effect what you were doing was to create a single element tuple as opposed to a string.
The documentation clearly says:
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
Unpacking multi-element tuple:
a, b = (12, 14)
print(type(a))
Output:
int
Unpacking single-element tuple:
a, = (12, )
print(type(a))
Output:
int
Otherwise:
a = (12,)
print(type(a))
Output:
tuple
In the question's example, you assigned the variable 'abc' to a Tuple with a length of 1.
You can do multiple assignments with this similar syntax:
x,y = 20,50
Also note that the print statement has a special understanding for ending a print statement with a comma; This tells print to omit the trailing newline.
print 'hello',
print 'world'
result:
hello world
I was somewhat confused about the application of the comma, as you also apply a comma to make a list instead of tuple, but with a different variable assignment.
Hereby, a simple example that I made of how to create a tuple or a list.
abc = 1,2,3 # prints a tuple: (1, 2, 3)
*abc, = 1,2,3 # prints a list: [1, 2, 3]
Why does adding a trailing comma after an expression create a tuple with the expression's value? E.g. in this code:
>>> abc = 'mystring',
>>> print(abc)
('mystring',)
Why is the printed output ('mystring',), and not just mystring?
It is the commas, not the parentheses, which are significant. The Python tutorial says:
A tuple consists of a number of values separated by commas
Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.
See the Python Tutorial section on Tuples and Sequences
Because this is the only way to write a tuple literal with one element. For list literals, the necessary brackets make the syntax unique, but because parantheses can also denote grouping, enclosing an expression in parentheses doesn't turn it into a tuple: you need a different syntactic element, in this case the comma.
Make sure to read this great answer by Ben James.
Tuples are not indicated by the parentheses. Any expression can be enclosed in parentheses, this is nothing special to tuples. It just happens that it is almost always necessary to use parentheses because it would otherwise be ambiguous, which is why the __str__ and __repr__ methods on a tuple will show them.
For instance:
abc = ('my', 'string')
abc = 'my', 'string'
What about single element tuples?
abc = ('mystring',)
abc = 'mystring',
So in effect what you were doing was to create a single element tuple as opposed to a string.
The documentation clearly says:
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
Unpacking multi-element tuple:
a, b = (12, 14)
print(type(a))
Output:
int
Unpacking single-element tuple:
a, = (12, )
print(type(a))
Output:
int
Otherwise:
a = (12,)
print(type(a))
Output:
tuple
In the question's example, you assigned the variable 'abc' to a Tuple with a length of 1.
You can do multiple assignments with this similar syntax:
x,y = 20,50
Also note that the print statement has a special understanding for ending a print statement with a comma; This tells print to omit the trailing newline.
print 'hello',
print 'world'
result:
hello world
I was somewhat confused about the application of the comma, as you also apply a comma to make a list instead of tuple, but with a different variable assignment.
Hereby, a simple example that I made of how to create a tuple or a list.
abc = 1,2,3 # prints a tuple: (1, 2, 3)
*abc, = 1,2,3 # prints a list: [1, 2, 3]
Why does adding a trailing comma after an expression create a tuple with the expression's value? E.g. in this code:
>>> abc = 'mystring',
>>> print(abc)
('mystring',)
Why is the printed output ('mystring',), and not just mystring?
It is the commas, not the parentheses, which are significant. The Python tutorial says:
A tuple consists of a number of values separated by commas
Parentheses are used for disambiguation in other places where commas are used, for example, enabling you to nest or enter a tuple as part of an argument list.
See the Python Tutorial section on Tuples and Sequences
Because this is the only way to write a tuple literal with one element. For list literals, the necessary brackets make the syntax unique, but because parantheses can also denote grouping, enclosing an expression in parentheses doesn't turn it into a tuple: you need a different syntactic element, in this case the comma.
Make sure to read this great answer by Ben James.
Tuples are not indicated by the parentheses. Any expression can be enclosed in parentheses, this is nothing special to tuples. It just happens that it is almost always necessary to use parentheses because it would otherwise be ambiguous, which is why the __str__ and __repr__ methods on a tuple will show them.
For instance:
abc = ('my', 'string')
abc = 'my', 'string'
What about single element tuples?
abc = ('mystring',)
abc = 'mystring',
So in effect what you were doing was to create a single element tuple as opposed to a string.
The documentation clearly says:
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
Unpacking multi-element tuple:
a, b = (12, 14)
print(type(a))
Output:
int
Unpacking single-element tuple:
a, = (12, )
print(type(a))
Output:
int
Otherwise:
a = (12,)
print(type(a))
Output:
tuple
In the question's example, you assigned the variable 'abc' to a Tuple with a length of 1.
You can do multiple assignments with this similar syntax:
x,y = 20,50
Also note that the print statement has a special understanding for ending a print statement with a comma; This tells print to omit the trailing newline.
print 'hello',
print 'world'
result:
hello world
I was somewhat confused about the application of the comma, as you also apply a comma to make a list instead of tuple, but with a different variable assignment.
Hereby, a simple example that I made of how to create a tuple or a list.
abc = 1,2,3 # prints a tuple: (1, 2, 3)
*abc, = 1,2,3 # prints a list: [1, 2, 3]
I am a Perl user for many years and started Python recently.
I learned that there is always "one obvious way" to do certain things. I wish to check the "one" way to translate my coding style in Perl below into Python. Thanks!
The objective is to:
Detect the existance of the pattern
If found, extract certain portion of the pattern
Perl:
if ($str =~ /my(pat1)and(pat2)/) {
my ($var1, $var2) = ($1, $2);
}
As far as I had learn for Python, below is how I am coding now. It seems to be taking more steps than Perl. That's why I have doubt about my Python code.
mySearch = re.search ( r'my(pat1)and(pat2)', str )
if mySearch:
var1 = mySearch.group(1)
var2 = mySearch.group(2)
Python doesn't prioritize pattern matching and string manipulation like perl does. These are analogous patterns, and yeah, Python's is longer (it's also got a lot of great things going for it, like the fact it's OOP and doesn't use weird magical global variables).
For the record though, you can be using tuple unpacking to make this more succinct:
var1, var2 = mySearch.groups()
Update:
Tuple unpacking
Tuple unpacking is a useful feature in Python. To understand it, let's first ask, what is a tuple. A tuple is, at its heart, an immutable sequence -- unlike with a list, you cannot append or pop or any of that stuff. Syntactically, it's very simple to declare a tuple -- it's just a few values separated by commas.
my_tuple = "I", "am", "awesome"
my_tuple[0] # "I"
my_tuple[1] # "am"
my_tuple[2] # "awesome"
People often think a tuple is in fact defined by surrounding parentheses -- my_tuple = ("I", "am", "awesome") -- but this is wrong; the parentheses are only useful insofar as they clarify or enforce a certain order of operations.
Tuple unpacking is one of the sweetest features in Python. You define a tuple data structure containing undefined names on the left, and you unpack the iterable on the right into it. The right side can contain any kind of iterable, but the shape of its contained data must exactly match the tuple structure of names on the left.
# some_var and other_var are both undefined
print some_var # NameError: some_var is undefined
print other_var # NameError: other_var is undefined
my_iterable = ["so", "cool"]
# note that 'some_var, other_var' looks a whole lot like a tuple
some_var, other_var = my_iterable
print some_var # "so"
print other_var # "cool"
Again, we don't need a list on the right but any kind of iterable -- for example, a generator:
def some_generator():
yield 1
yield 2
yield 3
a, b, c = some_generator()
print a # 1
print b # 2
print c # 3
You can even do tuple unpacking with nested data structures.
nested_list = [1, [2, 3], 4]
# note that parentheses are necessary here to delimit tuples
a, (b, c), d = nested_list
If the iterable on the right doesn't match the pattern on the left, things blow up:
# THESE EXAMPLES DON'T WORK
a, b = [1, 2, 3] # ValueError: too many values to unpack
a, b = [] # ValueError: need more than 0 values to unpack
Actually, this noisy failure makes tuple unpacking my favorite way to get an item from an iterable when I think that iterable should only have one item in it and I want my code to fail if it has more than one.
# note that the left side below is how you define a tuple of one
bank_statement, = bank_statements # we def want to blow up if too many statements
Multiple Assignment
What people think of as multiple assignment is actually just plain tuple unpacking.
a, b = 1, 2
print a # 1
print b # 2
This is nothing special. The interpreter evaluates the right hand side of the equation as a tuple -- remember, a tuple is just values (literals, variables, evaluated function calls, whatever) separated by a commas -- and then the interpreter matches it against the left side, just like it did with all the examples above.
Bringing it on home
I wrote this to explain the two different answers you were getting for this problem:
var1, var2 = mySearch.group(1), mySearch.group(2)
and
var1, var2 = mySearch.groups()
First, recognize that these two statements, for your situation -- where mySearch is a MatchObject resulting from a regex with two matching groups -- are entirely functionally equivalent.
They differ only very slightly in terms of the nature of the tuple unpacking. The first one declares a tuple on the right while the second uses the tuple returned by MatchObject.groups.
This does not really apply to your situation, but it might be useful to understand that MatchObject.group and MatchObject.groups have slightly different behavior (see here and here). MatchObject.groups returns all the 'subgroups' -- i.e. capturing groups -- that the regex encounters while MatchObject.group returns an individual group and counts the entire pattern as a group accessible at 0.
In reality, for this situation, you should use whichever of these two you think is most expressive or clearest. I personally think mentioning groups 1 and 2 on the right side is redundant and I am constantly annoyed by the fact that MatchObject.groups(0) returns the string matched by the entire pattern, thus offsetting all the 'subgroups' to one-indexing.
You can extract all groups at once and assign them to variables:
var1, var2 = mySeach.groups()
In Python you could do more than one variable assignments in a single line with comma as a delimiter.
var1, var2 = mySearch.group(1), mySearch.group(2)
Other answers says about tuple unpacking. So that would be better if you want to extract all the captured group contents to variables. If you want to grab particular groups contents, you must need to go for the method I mentioned.
va1, var2, var3 = mySearch.group(2), mySearch.group(3), mySearch.group(1)
Example:
>>> import re
>>> x = "foobarbuzzlorium"
>>> m = re.search(r'(foo)(bar.*)(lorium)', x)
>>> if m:
x, y = m.group(1), m.group(3)
print(x,y)
foo lorium