Is there any way to pop the first element from a Python tuple?
For example, for
tuple('A', 'B', 'C')
I would like to pop off the 'A' and have a tuple containing 'B' and 'C'.
Since tuples are immutable I understand that I need to copy them to a new tuple. But how can I filter out only the first element of the tuple?
With this tuple
x = ('A','B','C')
you can get a tuple containing all but the first element using a slice:
x[1:]
Result:
('B','C')
Related
I'm writing in Python and writing to a console with an array I am manipulating and have a syntax question.
The array is passed in and I create another another array for tracking position using along with sort the array but I dont see why when I want to access the iterable array it becomes a 2d array
posarr = [*enumerate(arr)]
posarr.sort(key = lambda it:it[1])
Then to access from a loop it is:
posarr[i][0] == blah
instead of
posarr[i] == blah
?
It's not a 2D array, it's a list of tuples. In each tuple, the first item is the index, and the second is the value (as you would expect from enumerate).
Forget about the sorting for now, just look at what posarr contains, for example:
>>> posarr = [*enumerate('cab')]
>>> posarr
[(0, 'c'), (1, 'a'), (2, 'b')]
BTW this has nothing to do with syntax.
Note: The enumerate() function assigns an index to each item in an iterable object
So, posarr = [*enumerate(arr)] will create a new array of tuples, where the first item of the tuple will be the index and the second item be the array element at that index.
After posarr = posarr.sort(key = lambda it:it[1]), posarr will be None because list.sort() does not return anything. It sorts an array in-place.
It should be like this: posarr.sort(key = lambda it:it[1]).
posarr[i] will return the tuple at index i, so to access the element at that index, you have to do something like this posarr[i][1]. posarr[i][0] is the index of the element posarr[i][1].
So, posarr is not a 2-D array, it is just an array of tuples.
I want to ask a question about zip() in python.
Consider the following simple code to demonstrate zip().
a = ['1', '2', '3']
b = ['a', 'b', 'c']
for key, value in zip(a, b):
print(key + value)
I know that the following output is produced:
1a
2b
3c
where each element in the corresponding lists are concatenated.
As a beginner in Python3, I understand the following about zip():
zip() creates a zip object, related to OOP that can be shown using list():
my_zip = zip(a, b)
print(my_zip)
print(list(my_zip))
>>> <zip object at 0xsomelocation>
>>>[('1', 'a'), ('2', 'b'), ('3', 'c')]
such that the zip object is a list of tuples.
My confusion is in this line from the original block of code, which I don't really understand:
for key, value in zip(a, b)
My interpretation is that as we are looping through our zip object, which has some innate __next__() method called on by our for loop, we loop through each tuple in turn.
For our first iteration of the loop, we get:
('1', 'a')
and python assigns '1' and 'a' to our variables key and value respectively. This is repeated until the end of the list dimensions i.e. 3 times.
Is this the correct interpretation of what is happening in our code?
such that the zip object is a list of tuples.
zip() doesn't return a list of tuples. It returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.
The iterator stops when the shortest input iterable is exhausted. With a single iterable argument, it returns an iterator of 1-tuples. With no arguments, it returns an empty iterator.
and python assigns '1' and 'a' to our variables key and value respectively. This is repeated until the end of the list dimensions i.e. 3 times.
Yes. Rest of your interpretation is correct.
BONUS:
zip() should only be used with unequal length inputs when you don’t care about trailing, unmatched values from the longer iterables. If those values are important, use itertools.zip_longest() instead.
I have to create this function that has as inputs a String and a list of strings; and as output a list of the indices of strings that contain the String. I have done it, but then I should ordinate the indices according to the occurrences of the String in the strings. How can i do that? This is my code:
I added the 'count' under 'if' to count the occurrences, how can i use it to ordinate the indices according to that?
You can add a list of counts in each string to your function,
def function(s,lst):
l=[]
counts = []
for i in range(len(lst)):
if s in lst[i]:
counts += [lst[i].count(s)]
l += [i]
return l, counts
Here counts is a list in which each entry is the count of occurrences of s in the string in your input list. The function now returns two lists in a tuple, for example with the first tuple element being l and the second being counts. Note that i=-1 is redundant here as i is an element of the iterable made with range and assigning a value to it before the loop doesn't change it's loop value.
You can now sort the first list based on the second list using a line modified from this post,
out_fun = function(s,inp)
out = [x for x,_ in sorted(zip(out_fun[0],out_fun[1]), key = lambda x: x[1], reverse=True)]
inp is the list of strings, for example inp = ["hello", "cure", "access code"]. out_fun is the return tuple of two lists from the function function. s is the string of interest - here as in your original example it is 'c'.
What this line does is that it first creates a list of tuples using zip, where each first element of the tuple is is element from the list of indices and the second is from the list of occurrences. The program then sorts the tuples based on the second element in reverse order (largest first). The list comprehension fetches only the first element from each tuple in the sorted result, which is again the index list.
If you have questions about this solution, feel free to ask. You have a Python 2.7 tag - in Python 3.X you would need to use list(zip()) as zip returns a zip object rather than a list.
This is a more concise version of your program:
def function(s,lst):
t = [(i,x.count(s)) for i,x in enumerate(lst) if s in x]
return t
It uses a list comprehension to create and return a list of tuples t with first element being the index of the string that has the character s and second being the count. This is not necessarily more efficient, that would need to be checked. But it's a clean one-liner that at least to me is more readable.
The list of tuples can than be sorted in a similar way to the previous program, based on second tuple element i.e. count,
out_fun = function(s,inp)
out = [x for x,_ in sorted(out_fun, key = lambda x: x[1], reverse=True)]
for example if I had
array=[["A",1],["B",2],["C",1]]
is there any way I can find ["A",1] by just looking for "A"? I'm trying to use this in a situation where the first thing in the array is unique so there's no point in looking at the second, also I have no way of knowing what the second variable is
Iterate over items present inside the outer list and check that the first element of inner list satisfies a particular condition.
>>> a=[["A",1],["B",2],["C",1]]
>>> next(i for i in a if i[0] == 'A')
['A', 1]
>>> [i for i in a if i[0] == 'A']
[['A', 1]]
If you're in control of the datatype, depending on whate else you're doing with this object, a dictionary may be a better choice for this:
Rather than
array=[["A",1],["B",2],["C",1]]
use
d={"A":1, "B":2, "C":1}
Then you can access the element associated with "A" simply with
>> d["A"]
1
If you want to transform your list into a dictionary:
d = dict(array)
I was wondering how I would be able to append a list to a list?
x = []
x.append(list(('H4','H3')))
print x # [['H4', 'H3']]
x.append(list('H4'))
print x # [['H4', 'H3'], ['H','4']]
I was wondering how I could get [['H4', 'H3'], ['H4']] instead of [['H4', 'H3'], ['H','4']]. I scoured the web and I only saw x.extend which isn't really what I wanted :\
You can use [] instead of list:
x.append(['H4'])
The list function (which constructs a new list) takes an iterable in parameter and adds every element of the iterable in the list. BUT, strings are iterable in Python, so each element (characters here) are added as elements in the list. Using [] shortcut avoid that.
From the documentation:
list([iterable])
Return a list whose items are the same and in the same order as iterable‘s items. iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to iterable[:]. For instance, list('abc') returns ['a', 'b', 'c'] and list( (1, 2, 3) ) returns [1, 2, 3]. If no argument is given, returns a new empty list, [].