List formation in python - python

I need to put 3 items in the list.
state..eg(1,2)
action...eg..west
cost....5
list=[(state,action,cost), (state,action,cost).........]
how can i make it in a form of list. For a particular state , action and cost is there. Moreover, if i need only state from the list, i should be able to extract it from the list.same thing goes for action too.

Your wording is pretty obscure. Right now you have a list of tuples (horribly named list, which robs the use of the built-in name from the rest of that scope -- please don't reuse built-in names as your own identifiers... call them alist or mylist, if you can't think of a more meaningful and helpful name!). If you want a list of lists, code:
alist = [[state, action, cost], [state, action, cost], ...]
If you want to transform the list of tuples in a list of lists,
alist = [list(t) for t in alist]
(see why you should never usurp built-in identifiers such as list?!-).
If you want to flatten the list-of-lists (or -of-tuples) into a single list,
aflatlist = [x for t in alist for x in t]
To access e.g. "just the state" (first item), say of the Nth item in the list,
justthestate = alist[N][0]
or, if you've flattened it,
justhestate = aflatlist[N*3 + 0]
(the + 0 is clearly redundant, but it's there to show you what to do for the cost, which would be at + 1, etc).
If you want a list with all states,
allstates = [t[0] for t in alist]
or
allstates = aflatlist[0::3]
I'm sure you could mean something even different from this dozen of possible interpretations of your arcane words, but I'm out of juice by now;-).

I'm not sure I understand the first part of your question ("form of a list"). You can construct the list of tuples in the form you've stated:
mylist = [(1, 'west', 5), (1, 'east', 3), (2, 'west', 6)]
# add another tuple
mylist.append((2, 'east', 7))
To extract only the states or actions (i.e. the first or second item in each tuple), you can use list comprehensions:
states = [item[0] for item in mylist]
actions = [item[1] for item in mylist]

The code you listed above is a list of tuples - which pretty much matches what you're asking for.
From the example above, list[0][0] returns the state from the first tuple, list[0][1] the action, and list[0][2] the cost.
You can extract the values with something like (state, action, cost)= list[i] too.

try this
l = [('a',1,2),('b',3,4),('a',4,6), ('a',6,8)]
state = [sl[0] for sl in l]
or for more,
state = [sl[0] for sl in l if 'a' in sl]

Related

How do I sum the first two values in each tuple in a list of tuples in Python?

I searched through stackoverflow but couldn't find an answer or adapt similar codes, unfortunately.
The problem is that I have a list of tuples:
tupl = [(5,3,33), (2,5,2), (4,1,7)]
and I should use list comprehension to have this output:
[8,7,5]
The code that I wrote is a bit dump and is:
sum_tupl = []
tupl = [(5,3,33), (2,5,2), (4,1,7)]
sum_tupl = [tupl[0][0]+tupl[0][1] for tuple in tupl]
sum_tupl
but instead of doing what I want it to do, it returns
[8,8,8]
which is the sum of the first couple executed three times.
I tried using a variant:
tupl = [(5,3,33), (2,5,2), (4,1,7)]
sum_tupl = [sum(tupl[0],tupl[1]) for tuple in tupl]
sum_tupl
(which is missing something) but to no avail.
Note: When you're beginning python, it's much easier to use loops instead of list comprehensions because then you can debug your code more easily, either by using print() statements or by stepping through it using a debugger.
Now, on to the answer:
When you do for x in y, with a list y, the individual items go in x. So for your code for tuple in tupl, you shouldn't use tupl because that is the entire list. You need to use the individual item in the list, i.e. tuple.
Note that it's not a good idea to name a variable tuple because that's already a builtin type in python.
You need:
tupl = [(5,3,33), (2,5,2), (4,1,7)]
sum_tupl = [t[0]+t[1] for t in tupl]
Which gives the list
sum_tupl: [8, 7, 5]
If you have more elements you want to sum, it makes more sense to use the sum() function and a slice of t instead of writing out everything. For example, if you wanted to sum the first 5 elements, you'd write
sum_tupl = [sum(t[0:5]) for t in tupl]
instead of
sum_tupl = [t[0]+t[1]+t[2]+t[3]+t[4] for t in tupl]
Each loop iteration you're accessing the first element of your tupl list, instead of using the current element. This is what you want:
sum_tupl = [t[0] + t[1] for t in tupl]
I prefer slicing:
>>> [x + y for x, y, *_ in tupl]
[8, 7, 5]
>>>

Python list comprehension filtering with tuples (containing integers as strings)

I am trying to filter the following list:
tuple = [('7:29', 0.5), ('99:2', 0.35714285714285715), ('10:2', 0.35714285714285715)] using list comprehension, filtering based on the first elements from the tuples between the character ':'.
For example: filter = [7, 99], thus the result would be: new_tuple = [('7:29', 0.5), ('99:2', 0.35714285714285715)].
I tried the following solution:
filter_string = [str(item) for item in filter]
tuple_filtered = [(x,y) for (x,y) in tuples if x in filter]
but it returns an empty list and I don't have any idea how to fix it.
Can somebody please help me?
First when you apply this line:
filter_string = [str(item) for item in filter]
You apply str() function over a tuple object - making all the tuple in to a string.
for example - str(('99:2', 0.35714285714285715)) --> '(\\'99:2\\', 0.35714285714285715)'
Which in my sense just make it harder to parse.
Second, tuple is a saved name in python - do not use it and run it over!
it can cause very annoying bugs later on.
Finally, you can look at a tuple as a fixed size array which is indexed, which mean you can address the first element (that you want to filter by)
Something like that:
my_tuples = [('7:29', 0.5), ('99:2', 0.35714285714285715), ('10:2', 0.35714285714285715)]
my_filter = [7, 99]
filtered_list = [t for t in my_tuples if int(t[0].split(':')[0])
in my_filter]
[(x,y) for (x,y) in tuples if str(x.split(":")[0]) in filter_string ]
Equivalently:
op = []
for (x,y) in tuples :
if str(x.split(":")[0]) in filter_string:
op.append((x,y))

out = [item for t in lt for item in t] how this will get executed

out = [item for t in lt for item in t], how this loop will get executed, please elaborate this as I am a beginner in python so I am having difficulty to understand this concept
lt = [('Geeks', 2), ('For', 4), ('geek', '6')]
out = [item for t in lt for item in t]
print(out)
Your list comprehension will be executed as:
out = []
for t in lt:
for item in t:
out.append(item)
The result will be a flattened list.
Notice that the left-to-right order of the for loops in the list comprehension is the same as the outer-to-inner order of the for loops in the expanded version.
lst = [item for t in lt for item in t]
The above code is similar to the below one,
lst = []
for t in lt:
for item in t:
lst.append(item)
List comprehension:
List comprehensions provide a concise way to create lists. It consists
of brackets containing an expression followed by a for clause, then
zero or more for or if clauses. The expressions can be anything,
meaning you can put in all kinds of objects in lists.
lt = [('Geeks', 2), ('For', 4), ('geek', '6')]
out = [item for t in lt for item in t]
print(out)
in code you have Double Iteration in List Comprehension and it is equivalent to:
out = []
for t in lt:
for item in t:
out.append(item)
print(out)
List Comprehensions
List comprehensions provide a concise way to create lists.
It consists of brackets containing an expression followed by a for
clause, then zero or more for or if clauses. The expressions can be
anything, meaning you can put in all kinds of objects in lists.
The result will be a new list resulting from evaluating the expression
in the context of the for and if clauses which follow it.
Syntax
The list comprehension starts with a '[' and ']', to help you
remember that the result is going to be a list.
The basic syntax is:
[ expression for item in list if conditional ]
This is equivalent to:
for item in list:
if conditional:
expression
Let's break this down and see what it does
new_list = [expression(i) for i in old_list if filter(i)]
new_list : The new list (result).
expression(i): Expression is based on the variable used for each
element in the old list.
for i in old_list: The word for followed by the variable name to
use, followed by the word in the old list.
if filter(i): Apply a filter with an If-statement.
Let's go step by step by order of the process:
It will first iterate through the list called lt
Then, iterate through the t which is every value in lt, it's a nested loop right now,
[('Geeks', 2), ('For', 4), ('geek', '6')]
t t t
item item item item item item
And then, we finally at the end return every item, which results into 6 elements in the list.

How can you loop over lists of tuples where you compare the tuple in one list to the other tuples in the same list?

for x in check:
this = sorted(x) #the first tuple
for y in check:
that = sorted(y) #the other tuples in the list? in order to compare with 'this'.
if this == that:
check.remove(x)
print(check)
I basically want to check for every list (in the list 'check') if there are tuples that are the same, such as (1, 3) and (3, 1). Then I want to remove the the last one ((3,1)) out of the list 'check'. However, the function returns a "list.remove(x): x not in list" error when I use "check.remove(x)". When I used "check.remove(y)", the result was :
output of "check.remove(y)"
I noticed that the first tuple (of the tuple with the same value) got deleted and that in the second last list, that there is still a pair of tuples that have the same values.
How the list 'check' looks like
How can I compare the tuples with each other in the same list and remove the second one that contains the same values?
Repeated removal from a list is never a good a idea since it is O(N).
You can do the cleaning in one non-nested run-through, however. It is better to build a clean list from scratch and possibly reassign it to the same variable:
seen, no_dupes = set(), []
for c in check:
s = tuple(sorted(c))
if s not in seen:
seen.add(s)
no_dupes.append(c)
# check[:] = no_dupes # if you must
Use in and not ==
for x in check:
this = sorted(x) #the first tuple
for y in check:
that = sorted(y) #the other tuples in the list? in order to compare with 'this'.
if this in that:
check.remove(x)
# alternatively you might need to loop through this if its a tuple of tuples
# for t in this:
# if t in that:
# check.remove(x)
print(check)
Consider the instance [(1,1), (1,1), (1,1)]
In the first iteration, x is assigned to the first element in the list, y is also assigned to the first element, since x=y, remove x. Now when y is iterated to the second element, x=y, but now x has already been removed in the previous iteration. You should use dynamic programming:
new_check = []
for x in check:
this = sorted(x)
if x not in new_check:
new_check.append(x)
return new_check

How to check if two lists of tuples are identical

I need to check to see if a list of tuples is sorted, by the first attribute of the tuple. Initially, I thaught to check this list against its sorted self. such as...
list1 = [(1, 2), (4, 6), (3, 10)]
sortedlist1 = sorted(list1, reverse=True)
How can I then check to see if list1 is identical to sortedlist1? Identical, as in list1[0] == sortedlist1[0], and list1[1] == sortedlist1[1].
The list may have a length of 5 or possibly 100, so carrying out list1[0] == sortedlist1[0], and list1[1] == sortedlist1[1] would not be an option because I am not sure how long the list is.
Thanks
I believe you can just do list1 == sortedlist1, without having to look into each element individually.
#joce already provided an excellent answer (and I would suggest accepting that one as it is more concise and directly answers your question), but I wanted to address this portion of your original post:
The list may have a length of 5 or possibly 100, so carrying out list1[0] == sortedlist1[0], and list1[1] == sortedlist1[1] would not be an option because I am not sure how long the list is.
If you want to compare every element of two lists, you do not need to know exactly how long the lists are. Programming is all about being lazy, so you can bet no good programmer would write out that many comparisons by hand!
Instead, we can iterate through both lists with an index. This will allow us to perform operations on each element of the two lists simultaneously. Here's an example:
def compare_lists(list1, list2):
# Let's initialize our index to the first element
# in any list: element #0.
i = 0
# And now we walk through the lists. We have to be
# careful that we do not walk outside the lists,
# though...
while i < len(list1) and i < len(list2):
if list1[i] != list2[i]:
# If any two elements are not equal, say so.
return False
# We made it all the way through at least one list.
# However, they may have been different lengths. We
# should check that the index is at the end of both
# lists.
if i != (len(list1) - 1) or i != (len(list2) - 2):
# The index is not at the end of one of the lists.
return False
# At this point we know two things:
# 1. Each element we compared was equal.
# 2. The index is at the end of both lists.
# Therefore, we compared every element of both lists
# and they were equal. So we can safely say the lists
# are in fact equal.
return True
That said, this is such a common thing to check for that Python has this functionality built in through the quality operator, ==. So it's much easier to simply write:
list1 == list2
If you want to check if a list is sorted or not a very simple solution comes to mind:
last_elem, is_sorted = None, True
for elem in mylist:
if last_elem is not None:
if elem[0] < last_elem[0]:
is_sorted = False
break
last_elem = elem
This has the added advantage of only going over your list once. If you sort it and then compare it, you're going over the list at least greater than once.
If you still want to do it that way, here's another method:
list1 = [(1, 2), (4, 6), (3, 10)]
sortedlist1 = sorted(list1, reverse=True)
all_equal = all(i[0] == j[0] for i, j in zip(list1, sortedlist1))
In python 3.x, you can check if two lists of tuples
a and b are equal using the eq operator
import operator
a = [(1,2),(3,4)]
b = [(3,4),(1,2)]
# convert both lists to sets before calling the eq function
print(operator.eq(set(a),set(b))) #True
Use this:
sorted(list1) == sorted(list2)

Categories