List of Dictionary Values - python

I have the dictionary as below:
tf ={1: ['a', 'b', 'c'], 2: ['d', 'x', 'y']}
I want to form the list of values as:
wrd_list = ['a', 'b', 'c', 'd', 'x', 'y']
I tried to do this by using the following code:
wrd_list = []
for k, v in tf.items():
for i in v:
word_list.append(i)
is there any efficient way to do this?

Using extend here is faster than append when you want to concatenate lists:
word_list = []
for v in tf.values():
word_list.extend(v)

Related

python - form new list from n elements to the right of a reoccurring word

Given a list of strings:
haystack = ['hay','hay','hay','needle','x','y','z','hay','hay','hay','hay','needle','a','b','c']
Question
How would I form a new list of strings that contain, say, only the three adjacent elements (to the right) of every 'needle' occurrence within haystack?
Find all the indices of "needle" and take 3 values right the indices.
# Get all indices of "needle"
idx = [idx for idx, val in enumerate(haystack) if val=="needle"]
#idx -> [3, 11]
# Take 3 values right of each index in `idx`.
[val for i in idx for val in haystack[i: i+4]]
# ['needle', 'x', 'y', 'z', 'needle', 'a', 'b', 'c']
# want it to be a list of list
[haystack[i: i+4] for i in idx]
# [['needle', 'x', 'y', 'z'], ['needle', 'a', 'b', 'c']]
# Want to exclude the "needle"
[val for i in idx for val in haystack[i+1: i+4]]
# ['x', 'y', 'z', 'a', 'b', 'c']
This is a kind of hacky solution, but it works with only one pass through the list.
it = iter(haystack)
output = [[next(it), next(it), next(it)] for s in it if s == 'needle']
# [['x', 'y', 'z'], ['a', 'b', 'c']]
This is essentially the short-form of the following:
it = iter(haystack)
output = []
while True:
try:
elem = next(it)
if elem == 'needle':
output.append([next(it), next(it), next(it)])
except StopIteration:
break
note that, in the short form, you'll get a StopIteration error if there are fewer than three elements following a 'needle'.
A simple list comprehension with list slicing seems to work as well:
out = [haystack[i+1:i+4] for i, x in enumerate(haystack) if x == 'needle']
Output:
[['x', 'y', 'z'], ['a', 'b', 'c']]
If I understood correctly then you want this...
for i in [i for i,ele in enumerate(haystack) if ele=="needle"]:
Out.extend(haystack[i+1:i+4])
print(Out)
Output
['x', 'y', 'z', 'a', 'b', 'c']

How would you re-order the reordered list back to its previous form?

element = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
index_list = [3,5,6,1,2,4,0]
result = [element[i] for i in index_list]
print(result)
this would eventually give me a ordered list based on the index list which would give
['d', 'f', 'g', 'b', 'c', 'e', 'a'].
How would you re-order this already re-ordered list back to its previous form which would be ['a', 'b', 'c', 'd', 'e', 'f', 'g']? I tried using the given index list again but it did not returned it back, but simply gave me a new list. Would there be any way I could still use the given index list to reorder the list back?
You can do the opposite:
reordered = [None] * len(result)
for index, e in zip(index_list, result):
reordered[index] = e
You can process index_list to do the reverse permutation:
index_list = [3,5,6,1,2,4,0]
reverse = [i for i, n in sorted(enumerate(index_list), key=lambda x: x[1])]
original = [result[i] for i in reverse]
something like this
print([a for a, b in sorted(zip(result, index_list), key=lambda x: x[1])])

Why are the keys of a dictionary going inside the items?

I have a problem that it seems to me that it doesn't make sense. I am defining a dictionary and using it to generate a list, with keys as the first elements of the list. But when I run it, not only the list is created, but the dictionary is modified. I need to know why this is happening and in which other way I could do this list without modifying the dictionary. A generical code example is the following:
class report:
def __init__(self):
self.dict_content= self.get_dict()
self.labels = self.get_labels()
def get_dict(self):
dict_content = dict(A1 = ['a', 'b', 'c'], A2 = ['d', 'e', 'f'])
return dict_content
def get_labels(self):
labels = []
for item in self.dict_content.items():
new_items = item[1]
new_items.insert(0, item[0])
labels.append(new_items)
return labels
Calling in the console,
r = report()
labels = r.labels
print(labels)
[['A1', 'a', 'b', 'c'], ['A2', 'd', 'e', 'f']]
dict_content = r.dict_content
print(dict_content)
{'A1': ['A1', 'a', 'b', 'c'], 'A2': ['A2', 'd', 'e', 'f']}
If I comment the line self.labels = self.get_labels() and do the last operations, I get:
r = report()
dict_content = r.dict_content
print(dict_content)
{'A1': ['a', 'b', 'c'], 'A2': ['d', 'e', 'f']}
And what I expect it to be is:
r = report()
labels = r.labels
print(labels)
[['A1', 'a', 'b', 'c'], ['A2', 'd', 'e', 'f']]
dict_content = r.dict_content
print(dict_content)
{'A1': ['a', 'b', 'c'], 'A2': ['d', 'e', 'f']}
What is happening?
for item in self.dict_content.items():
new_items = item[1]
new_items.insert(0, item[0])
labels.append(new_items)
Here, new_items, despite its name, is not a new list, but a reference to the original list contained in dict_content.
By using its insert method, you modify this list, which is reflected when looking at dict_content later.
Instead of modifying the original list, you want to create a new list. For example, by concatenation:
for item in self.dict_content.items():
new_items = [item[0]] + item[1]
labels.append(new_items)

I need help using Dictionary of dictionary python

I am trying to collect items in a dictionary:
enter code here
key1:
[
('text1', ['a', 'b', 'c']),
('text2', ['f', 'g']),
('text3',['h','i'])
]
#I tried to use collections.defaultdict() as
mydict = collections.defaultdict(list)
temp = collections.defaultdict(list)
temp["text1"].append(['a', 'b', 'c'])
temp["text2"].append(['f', 'g'])
temp["text3"].append(['h','i'])
mydict[key] = temp
I am confused and I am new to python. Above structure doesn't need to be a list I just wanted to hold these multiple things with key1, there would be multiple keys like key1.
Please advice me the best way I can do it, Also I want to sort this dictionary based on the top level keys (key1, key2 etc).
temp = {}
mydict = {}
temp["text1"] = ['a', 'b', 'c']
temp["text2"] = ['f', 'g']
temp["text3"] = ['h','i']
mydict['key1'] = list(temp.items())
mydict
the output is:
{'key1': [('text1', ['a', 'b', 'c']),
('text2', ['f', 'g']),
('text3', ['h', 'i'])]}

How to get duplicate values across any, potentially not all, lists

I have a dataset along the lines of:
data.append(['a', 'b', 'c'], ['a', 'x', 'y', z'], ['a', 'x', 'e', 'f'], ['a'])
I've searched SO and found ways to return duplicates across all lists using intersection_update() (so, in this example, 'a'), but I actually want to return duplicates from any lists, i.e.,:
retVal = ['a', 'x']
Since 'a' and 'x' are duplicated at least once among all lists. Is there a built-in for Python 2.7 that can do this?
Use a Counter to determine the number of each item and chain.from_iterable to pass the items from the sublists to the Counter.
from itertools import chain
from collections import Counter
data=[['a', 'b', 'c'], ['a', 'x', 'y', 'z'], ['a', 'x', 'e', 'f'], ['a']]
c = Counter(chain.from_iterable(data))
retVal = [k for k, count in c.items() if count >= 2]
print(retVal)
#['x', 'a']

Categories

Resources