I'm trying to create a list with words and integer values and put them in the list together. For example,
keywords:
rain,10
shine,5
python,10
great,1
Well i know how to put the words in a list, but not the values. So I did so far:
pyList = {'python', 'great, 'shine', rain}
So basically im trying to input the keywords and their values and store them in a list.
I agree with the other answers that a dictionary is the best way to accomplish this, but if you are looking strictly for a way to put these items in a list together, you may consider creating a list of tuples.
a_list = [("rain", 10), ("shine", 5), ("python", 10), ("great", 1)]
When you want to access this data:
print(a_list)
Will output: [('rain', 10), ('shine', 5), ('python', 10), ('great', 1)]
To access either item independently:
for x, y in a_list:
print(x)
Will output:
rain
shine
python
great
Of course x in the code above can be replaced with y to output the second part of the tuple instead.
A dictionary might be better than a list.
item_dict = {'rain': 10, 'shine': 5, 'python': 10, 'great': 1}
The following code
print(item_dict['rain'])
will output 10
If you don't care what numbers they have, but just want a different one for each then you can enumerate a list and turn that into a dictionary.
items = ['rain','shine','python','great']
items_dict = dict(enumerate(items))
This will give you a dictionary with the following values
{0: 'rain', 1: 'shine', 2: 'python', 3: 'great'}
Related
Edit: Solved
I've solved this by creating dictionaries a and b where the keys are the tuples (x,y) and my values are the integers t. I then return my keys as sets, take the built-in intersection, then get the values for all intersecting (x,y) points.
a{(x,y): t, ...}
b{(x,y): t, ...}
c = set([*a]).intersection(set([*b]))
for each in c:
val_a = a.get(each)
val_b = b.get(each)
Original Question
I have two sets of tuples, each of the form
a = {(x,y,t), (x,y,t), ...}
b = {(x,y,t), (x,y,t), ...}
I'd like to find the "intersection" of a and b while ignoring the t element of the tuples.
For example:
a = {(1,2,5), (4,6,7)}
b = {(1,2,7), (5,5,3)}
c = a.magicintersection(b,'ignore-last-element-of-tuple-magic-keyword')
where c, the desired output, would yield {(1,2,5), (1,2,7)}.
I'd like to leverage the built-in intersection function rather than writing my own (horribly inefficient) function but I can't see a way around this.
You cant use the built in intersection methods for that. You also can't attach function to built ins:
def magic_intersect(x):
pass
set.mi = magic_intersect
results in
set.mi = magic_intersect
TypeError: can't set attributes of built-in/extension type 'set'
You could prop them all into a dictionary with keys of the 1st two elements of each tuple and values of set/list all tuples that match this to get the result:
a = {(1,2,5), (4,6,7)}
b = {(1,2,7), (5,5,3)}
from collections import defaultdict
d = defaultdict(set)
for x in (a,b):
for s in x:
d[(s[0],s[1])].add(s)
print(d)
print(d.get( (1,2) )) # get all tuples that start with (1,2,_)
Output:
defaultdict(<class 'set'>, {
(4, 6): {(4, 6, 7)},
(1, 2): {(1, 2, 5), (1, 2, 7)},
(5, 5): {(5, 5, 3)}})
{(1, 2, 5), (1, 2, 7)}
but thats only going to be worth it if you need to query for those multiple times and do not need to put millions of sets in them.
The actual "lookup" of what 2-tuple has which 3-tuples is O(1) fast - but you need space/time to build the dictionary.
This approch looses the information from wich set of tuples the items came - if you need to preserve that as well, you would have to store that as well - somehow.
What would your "intersection" have as a result, if the third component varies?
Anyway, the way to do this is to have a dictionary where the key is a tuple with the components of interest. The dictionary values can be lists with all matching 3-tuples, and then you can select just those which have more than one element.
This is not inefficient, you will only have to walk each set once - so it is O(M + N) - and you have a lot of lists and thousands of tuples with the the same x, y - then building the dictionary will append the matching tuples to a list, which is O(1).
matches = {}
for series_of_tuples in (a, b):
for tuple in series_of_tuples:
matches.setdefault(tuple[:2], []).append(tuple)
intersection = [values for values in matches.values() if len(values) > 1]
In general, converting a list to set is simple, as below:
a = [1,2,3,1]
set_a = set(a) # set([1, 2, 3])
Now, I want to convert a list of tuples to set, only considering the first value of tuple.
a = [(1,"a1"), (2,"b2"), (3, "c3"), (1, "d4")]
set_a = some_magic(a)
# 1) set_a = set([(1,"a1"), (2,"b2"), (3, "c3")]) or
# 2) set_a = set([(1, "d4"), (2,"b2"), (3, "c3")])
# Both (1) or (2) are acceptible outputs.
Is there a "one-line" trick I could use instead of some_magic function mentioned above?
I want to avoid making a separate list for book-keeping which of the first index of tuples are already used [which would have been the obvious answer otherwise]
try this:
set(dict(a).items())
dict(a) will turn the list into a dictionary where the keys get overwritten by each occurrence
the .items() extracts each key-value pair into a dict_items list of tuples
the set() turns it into the set you want
Note: this will give you the second example, keeping the very last unique tuple key. If you want the first one, a different approach will be needed
Using list comprehension:
a = [(1,"a1"), (2,"b2"), (3, "c3"), (1, "d4")]
seen = set()
print([x for x in a if x[0] not in seen and not seen.add(x[0])])
OUTPUT:
[(1, 'a1'), (2, 'b2'), (3, 'c3')]
EDIT:
Using a dict:
print({x[0]: x for x in a}.values())
set_a = set(
{x[0]: x for x in a}.values()
)
you can convert to a dictionary to get rid of the duplicates
set(dict(a).items())
{(1, 'd4'), (2, 'b2'), (3, 'c3')}
This question already has answers here:
What does enumerate() mean?
(7 answers)
Closed 4 years ago.
First example:
my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 1):
print(c, value)
Another example:
[print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
How does x, d, and p work ?
So, there are two small questions here:
a)
my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 1):
print(c, value)
Step as follows:
enumerate(my_list, 1) will get a list with index, here the output is a enumereate object, if use list(enumerate(my_list, 1) to have a look, it is [(1, 'apple'), (2, 'banana'), (3, 'grapes'), (4, 'pear')].
So, with every for, the first iterate get c=1, value='apple', the second get c=2, value='banana' ...
Then the final output is:
1 apple
2 banana
3 grapes
4 pear
b)
[print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
Step as follows:
First, it's a list comprehension, I suppose you have known that.
The input first expect a user input, let's input 100 for example, then the input will treat it as a str, so [input()] returns ['100']
Then with for x in [input()] the x is '100'
Next according list comprehension, it will handle int(x)==sum(int(d)**p for p,d in enumerate(x,1))
(int(d)**p for p,d in enumerate(x,1)) will first iterate '100', get something like [(1, '1'), (2, '0'), (3, '0')] if use list to see it, just similar as example 1. Then calculate int(d)**p for every iterate and finally use sum to get the result, similar to int('1')**1 + int('0')**2 + int('0')**3, the result is 1.
So print(int('100')==1 certainly output False
And the return value of print function call is always None, so list comprehension will make the new list is [None].
So the final outout is (NOTE: 100 is the echo of your input):
>>> [print(int(x)==sum(int(d)**p for p,d in enumerate(x,1)))for x in[input()]]
100
False
[None]
It is good practice to look up things in the Python documentation when you have questions about built in functions like enumerate. A link to that is here.
To explain it, enumerate will help you iterate over all values in a list, and if you pass in an optional parameter number (like the 1 in your example), it specifies the starting index to iterate from.
What enumerate returns is first the index and then the item stored at that index in the list. So c in your example is going to be each index (1, 2, 3, etc) as it loops through the for loop. And value in your example is the actual value stored at that index in the list.
Also remember that lists start at index 0 instead of 1 as their first value.
The common naming system when using enumerate is idx, item it makes it clear what each element represents and would suit you best to follow this naming scheme
l = ['a', 'b', 'c']
print([(idx, item) for idx, item in enumerate(l)])
[(0, 'a'), (1, 'b'), (2, 'c')]
As you can see idx represents the index of the item, and item is the item.
I am looking for a code that can sort a list say for example list x, which contains integers and string. the code would then sort the list x so that the integer value is sorted corresponding to the string. so far I have tried this code however it does not work.
x =["a" 2,"c" 10, "b" 5]
x.sort()
print (x)
I want the result to be
["a" 2 "b" 5 "C" 10]
so the list is sorted numerically in acceding order and the string is also printed.
Use List of Tuples and then sort them according to what you want, example:
x = [('b',5),('a',2),('c',10)]
x.sort() # This will sort them based on item[0] of each tuple
x.sort(key=lambda s: s[1]) # This will sort them based on item[1] of each tuple
Another approach is to use dictionary instead of list of tuples, example:
x = {'b':5,'a':2,'c':10}#This will be automatically sorted based on the key of each element
if you print x, you will get:
{'a': 2, 'c': 10, 'b': 5}
if you want to sort them based on the value of each element, then:
x = sorted(x.items(), key=lambda s:s[1])
This will create a new list of tuples, since sorted() returns "new" sorted list, hence the result will be:
[('a', 2), ('b', 5), ('c', 10)]
If I deducted correctly you also want the resulting list to have an integer where the original list has an integer (and the same for characters).
I don't think there is an out-of-the-box way to do that. One possible approach is to separate your list into two others: one with integer, one with chars. Then, after sorting each list, you can merge them respecting the desired positions of integers and chars.
Use a nested iterable to pair the letters to numbers, then sort the items by the second elements:
# just pairs.sort(key = lambda x: x[1])
pairs = [('a', 2), ('c', 10), ('b', 5)]
I considered the elements are separate. The following code might help, you can fill or remove the print statement in the except block, as you wish.
x =["a", 2,"c", 10, "b", 5]
numbers = []
letters = []
for element in x:
try:
numbers.append(int(element))
except:
letters.append(str(element))
numbers.sort()
letters.sort()
numbers.reverse()
letters.reverse()
for index,item in enumerate(x):
try:
print int(item),
x[index] = numbers.pop()
except ValueError:
x[index] = letters.pop()
print "\n"+ str(x)
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]