python get list of partial strings from list of tuples - python

I have a list of tuples, its dates and times, from;to
print datetime
gives
[(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
I want to make a new list, but only of the 'to' times:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']
I cant seem to put all the elements together, so far I have
for a in datetime:
for b in a:
enddates = [b[b.find(";")+1:] for b in a]
print enddates
gives the last result only, not the list
[u'2017-09-10-13-45-23']
Have not given up easily, but down a rabbit hole on this

you don't need any loop, just pick the first & unique item from each tuple, and perform str.partition on it (take 2nd element: the rightmost one), in a list comprehension like you tried
a = [(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
enddates = [b[0].partition(";")[2] for b in a]
print(enddates)
result:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']

With str.split() function:
dt = [(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
result = [d[0].split(';')[1] for d in dt]
print(result)
Or the same with str.rfind() function:
...
result = [d[0][d[0].rfind(';')+1:] for d in dt]
The output:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']

Related

Repeat values in nested list

I am a total newbie and am doing prep work for the bootcamp. I got stuck with the the following Python exercise:
I have a nested list, say, [[1,2],[3,4]]. The first value in each sub-list is the value to repeat, the second is the amount of times to repeat that value.
I want to get a string with numbers repeated appropriate number of times, like "11, 3333". If there are multiple sets of values, they should be separated by commas; if there is only one set the comma should be omitted. I need to create a function.
I tried to create two separate sub-lists for values and number of repetitions, then np.repeat one list by another.
data_list =[[1,2],[3,4]]
num_list = [val [0] for val in data_list]
repeat_list = [val[1] for val in data_list]
result = np.repeat (num_list, repeat_list)
print (result)
[1 1 3 3 3 3]
In this case I do not know how to separate it with commas. And this is not a function.
I feel like I might need to use np.repeat with "for" loop, but I can not figure out exactly how should it look like.
Thanks.
You could do something like this:
result = ""
for sublist in nested_list:
# For each sublist, turn the first element into a string, and multiply it by the second element, then add a comma
result += str(sublist[0]) * sublist[1] + ","
# Remove the last trailing comma
result = result[:-1]
Without for loop and numpy
', '.join(
map(lambda l: str(l[0])*l[1], data_list)
)
Each entry in list map it to string, then join those strings together
A possible solution :
l= [[1, 2], [3, 4]]
final=[]
for i in l:
final.append(list(str(i[0]) * i[1]))
You could do like this.
data_list =[[1,2],[3,4]]
res = []
for i in data_list:
s = str(i[0]) * i[1]
res.append(s)
print(f'List: {res}')
print(f'String: {", ".join(res)}')
List: ['11', '3333']
String: 11, 3333

Print all elements of a list preceded by a given one

I want to print all the elements of this list who are directly following "apple".
With
my_list = ["apple","train","apple","bus"]
I would expect the output:
(train,bus)
But my current code
print (my_list[my_list.index("apple") + 1])
only outputs the first one, "train".
How can I get all of them?
If you want to get all items directly following an "apple" in your list, your could use a list comprehension, like:
my_list = ["apple","train","apple","bus", "apple"]
[my_list[i+1] for i, item in enumerate(my_list)
if item == "apple" and i+1 < len(my_list)]
# ['train', 'bus']
We keep the next element whenever the current one is "apple" - and we're not at the end of the list.
my_list = ["apple","train","apple","bus"]
index = my_list.index("apple")
print(my_list[index:index+2])
Have a look at Python's slice syntax. This will print the sublist from index to index + 2 (exclusive).
If you want it as a tuple as you indicated in your question, just wrap it in tuple()
Edit: Of course given that you already have apple you could also just do
print(("apple", my_list[my_list.index("apple") + 1)

Filtering for tuples from another list and extracting values

I am working on handling two lists of tuples and deducing results.
For example:
A = [('Hi','NNG'),('Good','VV'),...n]
B = [('Happy','VA',1.0),('Hi','NNG',0.5)...n]
First, I'd like to match the words between A and B.
like 'Hi'='Happy' or 'Hi'='Hi'
Second, if they are same and match, then match word class.
whether 'NNG'='NNG' or 'NNG'='VV'
Third, if all these steps match, then extract the number!
like if A=[('Hi','NNG')] and B=('Hi','NNG',0.5)
Extract 0.5
Lastly, I want to multiply all numbers from extraction.
There are more than 1,000 tuples in each A, B. So 'for' loop will be necessary to find out this process.
How can I do this in Python?
Try something like this:
A = [('Hi', 'NNG'), ('Good', 'VV')]
B = [('Happy', 'VA', 1.0), ('Hi', 'NNG', 0.5)]
print(', '.join(repr(j[2]) for i in A for j in B if i[0] == j[0] and i[1] == j[1]))
# 0.5
One way is to use a set and (optionally) a dictionary. The benefit of this method is you also keep the key data to know where your values originated.
A = [('Hi','NNG'),('Good','VV')]
B = [('Happy','VA',1.0),('Hi','NNG',0.5)]
A_set = set(A)
res = {(i[0], i[1]): i[2] for i in B if (i[0], i[1]) in A_set}
res = list(res.values())
# [0.5]
To multiply all results in the list, see How can I multiply all items in a list together with Python?
Explanation
Use a dictionary comprehension with for i in B. What this does is return a tuple of results iterating through each element of B.
For example, when iterating the first element, you will find i[0] = 'Happy', i[1] = 'VA', i[2] = 1.0.
Since we loop through the whole list, we construct a dictionary of results with tuple keys from the first 2 elements.
Additionally, we add the criterion (i[0], i[1]) in A_set to filter as per required logic.
Python is so high level that it feels like English. So, the following working solution can be written very easily with minimum experience:
A = [('Hi','NNG'),('Good','VV')]
B = [('Happy','VA',1.0),('Hi','NNG',0.5)]
tot = 1
for ia in A:
for ib in B:
if ia == ib[:2]:
tot *= ib[2]
break # remove this line if multiple successful checks are possible
print(tot) # -> 0.5
zip() is your friend:
for tupA,tupB in zip(A,B):
if tupA[:2] == tupB[:2] : print(tupB[2])
To use fancy pythonic list comprehension:
results = [tubB[2] for tubA,tubB in zip(A,B) if tubA[:2] == tubB[:2] ]
But... why do I have a sneaky feeling this isn't what you want to do?

Reverse characters of string in subset of 3

Let say my string is as:
x = 'abcdefghi'
I want to reverse it in subsets of 3, so that my output is:
x = 'cbafedihg'
i.e. 0th index is swapped with 2nd index, 3rd index swapped with 5th, and so on.
Below is my code based on converting the string to list and swap the elements within the list:
string_list = list(x)
for i in range(len(string_list)/3):
string_list[i*3], string_list[i*3+2] = string_list[i*3+2], string_list[i*3]
''.join(string_list)
# Output: 'cbafedihg'
I want to know what will be the most efficient and most pythonic way to achieve it.
Note: len(x)%3 will always be 0.
The above code can be written using string slicing and list comprehension as:
# Here x[i*3:i*3+3][::-1] will reverse the substring of 3 chars
>>> ''.join([x[i*3:i*3+3][::-1] for i in range(len(x)/3)])
'cbafedihg'
Based on the comment by Delgan, it could be further simplified using step as 3 with range itself as:
>>> ''.join(x[i:i+3][::-1] for i in range(0, len(x), 3))
'cbafedihg'
Writing a function that is more readable and flexible?
def get_string(input_str, step=3):
output = ""
i = 0
for _ in list(input_str):
if i == len(input_str):
return output
elif i+step-1 >= len(input_str):
output += input[len(input_str)-1:i-1:-1]
return output
else:
output += input_str[i+step-1:i:-1] + input_str[i]
i += step
return output
And here comes the flexible part:
get_string("abcdefghi")
# Ouputs 'cbafedihg'
get_string("abcdefghi", 2)
# Outputs 'badcfehgi'
get_string("abcdefghi", 5)
# Outputs 'edcbaihgf'
Not to mention, if you want to add some more logic or change the logic, it is easier to change here.
Another alternative to achieve this is to type-cast your string to list, then simply swap the elements of list using list slicing with step as 3, and join back the list of strings as:
>>> string_list = list(x)
>>> string_list[::3], string_list[2::3] = string_list[2::3], string_list[::3]
>>> ''.join(string_list)
'cbafedihg'

Add two lists in Python

I am trying to add together two lists so the first item of one list is added to the first item of the other list, second to second and so on to form a new list.
Currently I have:
def zipper(a,b):
list = [a[i] + b[i] for i in range(len(a))]
print 'The combined list of a and b is'
print list
a = input("\n\nInsert a list:")
b = input("\n\nInsert another list of equal length:")
zipper(a,b)
Upon entering two lists where one is a list of integers and one a list of strings I get the Type Error 'Can not cocanenate 'str' and 'int' objects.
I have tried converting both lists to strings using:
list = [str(a[i]) + str(b[i]) for i in range(len(a))]
however upon entering:
a = ['a','b','c','d']
b = [1,2,3,4]
I got the output as:
['a1','b2','c3','d4']
instead of what I wanted which was:
['a+1','b+2','c+3','d+4']
Does anyone have any suggestions as to what I am doing wrong?
N.B. I have to write a function that will essentially perform the same as zip(a,b) but I'm not allowed to use zip() anywhere in the function.
Zip first, then add (only not).
['%s+%s' % x for x in zip(a, b)]
What you should do
You should use
list = [str(a[i]) +"+"+ str(b[i]) for i in range(len(a))]
instead of
list = [str(a[i]) + str(b[i]) for i in range(len(a))]
In your version, you never say that you want the plus character in the output between the two elements. This is your error.
Sample output:
>>> a = [1,2,3]
>>> b = ['a','b','c']
>>> list = [str(a[i]) +"+"+ str(b[i]) for i in range(len(a))]
>>> list
['1+a', '2+b', '3+c']

Categories