I am getting some errors using list like it works when i try this
new_list=new_list+[temp]
but it didn't work when i use list(temp)
new_list=new_list+list(temp)
You have the error because you are trying to make a list with an integer:
temp = 1
print(list(temp))
output:
TypeError: 'int' object is not iterable
The list() constructor returns a mutable sequence list of elements. The iterable argument is optional. You can provide any sequence or collection (such as a string, list, tuple, set, dictionary, etc). If no argument is supplied, an empty list is returned.
The example below works fine because you are putting an integer inside a list:
temp = 1
print([temp])
output:
[1]
The list has been constructed using a pair of square brackets.
According to python official documentation, list object can be constructed in several ways:
Using a pair of square brackets to denote the empty list: []
Using square brackets, separating items with commas: [a], [a, b, c]
Using a list comprehension: [x for x in iterable]
Using the type constructor: list() or list(iterable)
So, [] is syntax literal and list() is builtin constructor function. For the latter, the argument accepted is iterable (If no argument is given, the constructor creates a new empty list, []), that's the reason list(1) throws TypeError.
Related
I have been working through a tutorial and encountered unfamiliar Python syntax. Looking to identify what it's called and learn how it works.
Mystery Code
The line(s) in question involve a variable name surrounded by square braces before being set:
[pivot] = get_point_by_id(svg_tree, 'pivot')
Relevant Clue to Posted Answers
My initial thought was that it had something to do with being set to a list since the return value from get_point_by_id is a list.
Untouched, the code runs fine. But if I try to recreate the syntax like this:
[variable_name] = [1,2,3]
print(variable_name)
I get the following error:
ValueError: too many values to unpack (expected 1)
I'll take a guess from your posting: in your first example, pivot is a list that happens to be of the same shape as the functional return. In contrast, variable_name in the second value is not a sequence of three scalars.
The list represents a sequence of values; you can assign the sequence to a matching sequence of variables. For instance:
>>> [a, b] = [2, 3]
>>> a
2
>>> b
3
we usually write this without brackets, simply
a, b = [2, 3]
The left-hand-side of the assignment is the target list.
From 7.2. Assignment statements:
Assignment of an object to a target list, optionally enclosed in
parentheses or square brackets, is recursively defined as follows.
If the target list is a single target with no trailing comma,
optionally in parentheses, the object is assigned to that target.
Else: The object must be an iterable with the same number of items as
there are targets in the target list, and the items are assigned, from
left to right, to the corresponding targets.
The following works because the number of items in the target list is the same as the in the object on the right-hand-side of the assignment.
In [17]: [a] = ['foo']
In [18]: a
Out[18]: 'foo'
In your mystery code, get_point_by_id must return an iterable with one item.
I want to use a function which takes tuples as an argument, however I have a list of tuples and whenever I try feeding the list of tuples to the function it returns
s = s.join(x)
TypeError: sequence item 0: expected str instance, tuple found
However with just one tuple on its own without a list around it, the function will work as expected.
Is there a way in which I can feed a list of tuples like this:
[('abcd','1234','xyz'),('e.t.c', 'e.t.c', 'test')]
to a function which takes single tuples on their own? Thanks :)
EDIT -
This is the function I am feeding the list of tuples to:
def strFormat(x):
#Convert to string
s=' '
s = s.join(x)
print(s)
#Split string into different parts
payR, dep, sal, *other, surn = s.split()
other = " ".join(other)
#Print formatting!
print ("{:5}, {:5} {:>10} {:10} £{:10}".format(surn , other, payR, dep, sal))
When putting a single tuple to this function it returns the print formatted string as expected. When putting a list of tuples to this function it does not work and returns an error. How do I make it so a list of tuples like the one above will work on the above function?
If you want to join the tuples separately you can use a list comprehension:
[delimiter.join(x) for x in list_of_tup] # delimiter should be a string
Otherwise you need to unpack the tuples then join them all. Which for that aim you can use a nested list comprehension or itertools.chain:
delimiter.join([item for tup in list_of_tup for item in tup])
This question already has answers here:
Why can tuples contain mutable items?
(8 answers)
Closed 6 years ago.
Here's 2 pieces of Python code:
t = (1, [2])
t[1] += [3]
and
t = (1, [2])
t[1].append(3)
The first piece firstly modifies the inner list t[1], and than throws an exception while trying to reassign value in the tuple. Though value of t has actually changed, this behaviour is more or less understandable. But the second piece of code changes the tuple without any error/exception/whatever (as I understand, because it changes list t[1] without reassignment).
The question is, doesn't this stuff contradict the immutability of tuples?
Tuples are immutable which means you cannot update or change the
values of tuple elements. You are able to take portions of existing
tuples to create new tuples as the following example demonstrates −
#!/usr/bin/python
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# Following action is not valid for tuples
# tup1[0] = 100;
# So let's create a new tuple as follows
tup3 = tup1 + tup2;
print tup3
When the above code is executed, it produces the following result −
(12, 34.56, 'abc', 'xyz')
But when you access the list in the tuple like t[1], you access the object reference which allows you use class functions. The immutable one is tuple, not the contained object.
I think the only thing you are missing is that "tuple is immutable" only means you can't change the references for the elements of the tuple. If an element is mutable, you can still mutate it.
The main rule here is: "A tuple itself is immutable. Its content, not."
When you are calling the append method, you're modifying an element of the tuple, not the tuple itself. So, the call is valid. You can see it in that sample:
tab = (new Object(), new Object(), new Object())
tab[1].changeContent();
Now, just replace the changeContent with the append method and you will see why it's valid. The value tab[1] still references the same object. But the object itself have changed.
But, when you are using the "plus" operator, it's not the same case.
When you call
tab[0] += [1]
It's rewritten as something like (if you suppose that "addWith" is the function that returns the result of the addition):
tab[0] = tab[0].addWith([1])
As you can see that it's modifying the tuple itself (it links the first cell to another object), it's why the call is invalid.
How do I create a simple tuple containing a variable of any time without creating a tuple of tuples? For example a function can accept either an int or a tuple of ints. Inside the function I want to make sure that the variable is in fact a tuple.
So far I could think of
a = tuple(a)
and
a = (a,)
However the first one doesnt work if a is not iterable and the second one creates a tuple of a tuple if a is already one.
((1,2),)
I feel like I should be able to do that without checking the type first... What am I missing?
You can use exception handling; try calling iter() on the object, for example
try:
iter(a)
except TypeError:
# not an iterable, assume a single value
a = (a,)
If you were planning to iterate over the tuple to handle values anyway, you just store the output of the iter() call and use it directly:
try:
a = iter(a)
except TypeError:
a = (a,)
for elem in a:
You can also make your function signature accept multiple parameters:
def foobar(*a):
for elem in a:
Now a is always a tuple, but to pass in a tuple you'd have to call it with:
sometuple = (1, 2, 3)
foobar(*sometuple)
while a single value is passed in as:
foobar(singlevalue)
You can use a lambda function:
a = (lambda x: x if type(x) is tuple else (x,))(a)
Perhaps more verbose than what you wanted, but it allows you to keep it all in one line.
Unfortunately, there's really no way to do it without checking the type of the argument. When you try to construct a tuple from another tuple - e.g. t = (tup,) - it's treated as a generic Python object, i.e. it doesn't "know" that it's a tuple. In order for it to auto-expand the tuple, it will have to check it's type first.
A non-iterable object would also have to be identified, because it doesn't contain the necessary methods to iterate over it's elements. In other words, a non-iterable - e.g. a scalar - isn't just an iterable with a single element. They're completely different object types. It can be placed in a tuple, but not converted to one.
When you use the tuple function to create a tuple, it just treats the input as a generic iterable. It doesn't know that it's a tuple.
So whether the type check is done internally by tuple(), or by the calling function, it will still have to be done.
a = "Stack"
aList = list(a)
This gives me an array like this ['S','t',a','c','k']
I want to know how this list(string) function works!
A string is an iterable type. For example, if you do this:
for c in 'string':
print c
You get
s
t
r
i
n
g
So passing a string to list just iterates over the characters in the string, and places each one in the list.
String is iterable in python because you can do
>>> for ch in "abc":
... print ch
...
a
b
c
>>>
and if you take a look at list class construtor using help("list") in your python interpreter
class list(object)
| list() -> new empty list
| list(iterable) -> new list initialized from iterable's items
So, list("hello") returns a new list initialized.
>>> x = list("hello")
>>> type(x)
<type 'list'>
>>>
This works because str implements __iter__, which allows iter(obj) to be called on the object. For str, the implementation returns character by character.
Most of the work is actually being done by the string. You are actually using the constructor of the list type. In Python, we are usually not so concerned with what things are, but rather with what they can do.
What a string can do is it can give you (e.g. for the purpose of using a for loop) its characters (actually, length-1 substrings; there isn't a separate character type) one at a time. The list constructor expects any object that can do this, and constructs a list that contains the elements thus provided.