Access elements in a Python tuple - python

I have a tuple like this:
('TRM',)
I would like to extract the string only from this tuple.
I did the following and it works but just thinking if there is a better way to do that.
>>> b = [x for x in a]
>>> b
['TRM']
>>> for i in b:
... print(i)
...
TRM
>>>

This will help you
b = [x for x in a if type(x) == type("Str")]
print(b)

If you need to access a specific element of the tuple you can do it by index:
>>> a[0]
TRM

Not exactly sure what you're asking for but you could do:
for i in b:
if isinstance(i, str):
print(i)
and this will print
TRM
Edit: Now it checks whether an element is a string.

Related

List comprehension from two sources

Having this input:
a = (1,2,3)
b = 'something'
I want to create a list which will look like that:
['something', 1, 2, 3]
I tried to do:
[b, i for i in a]
But got a syntax error.
Note that, I'm looking for a one line solution out of curiosity.
If your variable 'a' will always be a tuple and 'b' will always be a string then you can try one thing...
a = (1,2,3)
b = 'something'
c = [b] + [i for i in a]

Finding the number of lists in a tuple

I have a function that takes two inputs, both tuples, and checks to ensure they are the same size before continuing. I am having issues in trying to calculate the length of each tuple.
Examples:
tupA = ([1,2,3,4],[11,22,33,44])
tupB = ([1,2],[3,4],[5,6])
tupC = ([1,2,3,4,5,6,7,8,9])
When I take the length of each object it returns:
len(tupA) = 2
len(tupB) = 3
len(tupC) = 9
Is there an easy way to have the len(tupC) return 1? I found a workaround by adding a comma:
tupD = ([1,2,3,4,5,6],)
len(tupD) = 1
But I don't want to force the user to have to add the comma. Is there a better way to do this?
For such data
tupA = ([1,2,3,4],[11,22,33,44])
tupB = ([1,2],[3,4],[5,6])
tupC = ([1,2,3,4,5,6,7,8,9])
last one is not tuple, as you might check
print(type(tupC)) #prints <class 'list'>
You might check if variable is of given type using isinstance function, you could therefore create own function
def mylen(x):
if isinstance(x,list):
return 1
else:
return len(x)
Which will give 1 for your tupC, 3 for your tupB and 2 for your tupA.
You would have to have the comma to make the len work as you expect, as mentioned in the docs
A tuple with one item is constructed by following a value with a comma.
The only benefit of a tuple would be to make it immutable,
but if you use lists, there is no problem.
>>> listA = [[1,2,3,4],[11,22,33,44]]
>>> listB = [[1,2],[3,4],[5,6]]
>>> listC = [[1,2,3,4,5,6,7,8,9]]
>>> len(listA)
2
>>> len(listB)
3
>>> len(listC)
1
As discussed in comments, tupC is not a tuple, it's a list with 9 elements. It's a tuple only when there is a trailing comma.
As a workaround, we can check if it's a list and return results accordingly:
def length_(tupl):
return 1 if isinstance(tupl, list) else len(tupl)
Usage:
>>> tupA = ([1,2,3,4],[11,22,33,44])
>>> tupB = ([1,2],[3,4],[5,6])
>>> tupC = ([1,2,3,4,5,6,7,8,9])
>>> length_(tupA)
2
>>> length_(tupB)
3
>>> length_(tupC)
1
Notice that tupC is actually a list, not a tuple:
>>> tupA = ([1,2,3,4],[11,22,33,44])
>>> tupB = ([1,2],[3,4],[5,6])
>>> tupC = ([1,2,3,4,5,6,7,8,9])
>>> type(tupA), type(tupB), type(tupC)
(<class 'tuple'>, <class 'tuple'>, <class 'list'>)
If you still insist on keeping things as tuples of lists instead of lists of lists, and don't want to add the comma, you could define your own function to handle this:
>>> def newlength(x):
... if type(x) == list:
... return 1
... return len(x)
...
>>> print(newlength(tupA))
2
>>> print(newlength(tupB))
3
>>> print(newlength(tupC))
1
EDIT: Kudos to Daweo for beating me to an almost identical answer by a couple of minutes!

An iterator that doesn't squash references?

I want a for loop in Python that can modify variables in the iterator, not just handle the value of the variables. As a trivial example, the following clearly does not do what I want because b is still a string at the end.
a = 3
b = "4"
for x in (a, b):
x = int(x)
print("b is %s" % type(b))
(Result is "b is a <class 'str'>")
What is a good design pattern for "make changes to each variable in a long list of variables"?
Short answer: you can't do that.
a = "3"
b = "4"
for x in (a, b):
x = int(x)
Variables in Python are only tags that references values. Theres is not such thing as "tags on tags". When you write x = int(x) if the above code, you only change what x points to. Not the pointed value.
What is a good design pattern for "make changes to each variable in a long list of variables"?
I'm not sure to really understand, but if you want to do things like that, maybe you should store your values not as individual variables, but as value in a dictionary, or as instance variables of an object.
my_vars = {'a': "3",
'b': "4" }
for x in my_vars:
my_vars[x] = int(my_vars[x])
print type(my_vars['b'])
Now if you're in the hackish mood:
As your variables are globals they are in fact stored as entries in a dictionary (accessible through the globals() function). So you could change them:
a = "3"
b = "4"
for x in ('a', 'b'):
globals()[x] = int(globals()[x])
print type(b)
But, as of myself, I wouldn't call that "good design pattern"...
As mentioned in another answer, there's no way to update a variable indirectly. The best you can do is assign it explicitly with unpacking:
>>> a = 3
>>> b = 4
>>> a, b = [int(x) for x in a, b]
>>> print "b is %s" % type(b)
b is <type 'int'>
If you have an actual list of variables (as opposed to a number of individual variables you want to modify), then a list comprehension will do what you want:
>>> my_values = [3, "4"]
>>> my_values = [int(value) for value in my_values]
>>> print(my_values)
[3, 4]
If you want to do more complicated processing, you can define a function and use that in the list comprehension:
>>> my_values = [3, "4"]
>>> def number_crunching(value):
... return float(value)**1.42
...
>>> my_values = [number_crunching(value) for value in my_values]
>>> print(my_values)
[4.758961394052794, 7.160200567423779]

How to copy data in Python

After entering a command I am given data, that I then transform into a list. Once transformed into a list, how do I copy ALL of the data from that list [A], and save it - so when I enter a command and am given a second list of data [B], I can compare the two; and have data that is the same from the two lists cancel out - so what is not similar between [A] & [B] is output. For example...
List [A]
1
2
3
List [B]
1
2
3
4
Using Python, I now want to compare the two lists to each other, and then output the differences.
Output = 4
Hopefully this makes sense!
You can use set operations.
a = [1,2,3]
b = [1,2,3,4]
print set(b) - set(a)
to output the data in list format you can use the following print statement
print list(set(b) - set(a))
>>> b=[1,2,3,4]
>>> a=[1,2,3]
>>> [x for x in b if x not in a]
[4]
for element in b:
if element in a:
a.remove(element)
This answer will return a list not a set, and should take duplicates into account. That way [1,2,1] - [1,2] returns [1] not [].
Try itertools.izip_longest
import itertools
a = [1,2,3]
b = [1,2,3,4]
[y for x, y in itertools.izip_longest(a, b) if x != y]
# [4]
You could easily modify this further to return a duple for each difference, where the first item in the duple is the position in b and the second item is the value.
[(i, pair[1]) for i, pair in enumerate(itertools.izip_longest(a, b)) if pair[0] != pair[1]]
# [(3, 4)]
For entering the data use a loop:
def enterList():
result = []
while True:
value = raw_input()
if value:
result.append(value)
else:
return result
A = enterList()
B = enterList()
For comparing you can use zip to build pairs and compare each of them:
for a, b in zip(A, B):
if a != b:
print a, "!=", b
This will truncate the comparison at the length of the shorter list; use the solution in another answer given here using itertools.izip_longest() to handle that.

Get actual value from Python list

Say I have
a = [1,2,3]
b = [foo(x) for x in a]
Now b is something like [ < function at 0x00F91540>, ...], how do I get python to evaluate b into it's actual values?
--EDIT--
Sorry for the confusion, my frustration is that Python doesn't give me the actual values in b, hence when I try to do something like:
b[0] + 1
it gives me the below error:
TypeError: unsupported operand type(s) for +: 'function' and 'int'
Define your function outside the comprehension:
def foo(x):
return x + 1
a = [1,2,3]
b = [foo(x) for x in a]
Now, b == [2,3,4]. Or, as others have pointed out, just use the function body in the list comprehension:
[x + 1 for x in a]
...although this assumes that you can reproduce the function body in this way (which you won't be able to do for more complicated functions).
Note that the result of a lambda expression is the same as typing the name of a function, eg. lambda x: x+1 and foo represent the same thing: a function which needs a parameter given to it and returns a result. For the sake of clarification, this is how you'd "use" a lambda in a list comprehension:
[(lambda y: y+1)(x) for x in a]
...but seriously, don't do this ;)
If you just want the values, you don't need lambdas at all.
You can simply write:
b = [x + 1 for x in a]
If, for some reason, you still want to evaluate the lambdas that are in your version of b, you can write something like this:
c = [f(n) for f, n in zip(b, a)]
If I understand what you want it to do correctly, you don't need the lambda.
b = [x+1 for x in a]
should do what you want.
What you are doing is creating a list of lambda functions what you want is
a = [1,2,3]
b = [x+1 for x in a]

Categories

Resources