Python nested IF statement not iterating the entire list - python-3.x

I need some help in understanding why it's not iterating the complete list and how I can correct this. i need to replace some values between list B and List A to do another process. The code is supposed to give me a final list of
b = ['Sick', "Mid 1", "off", "Night", "Sick", "Morning", "Night"]
I was thinking of 2 nested IF statements, because it's evaluating 2 different things. My code gives me
['Sick', 'Mid 1', 'off', 'Night', 'off', 'Morning', 'Night']
which is correct on element [0], but not on element[4].
I was playing in the indentation of i = i+1
a = ['Sick', 'PR', '', 'PR', 'Sick', 'PR', 'PR']
b = ["off", "Mid 1", "off", "Night", "off", "Morning", "Night"]
i = 0
for x in the_list:
for y in see_drop_down_list:
if x =="off":
if y == "":
the_list[i] = "off"
else:
the_list[i]=see_drop_down_list[i]
i = i + 1
print (the_list)

You don't need to do double iteration here. Corrected code:
a = ['Sick', 'PR', '', 'PR', 'Sick', 'PR', 'PR']
b = ['off', 'Mid 1', 'off', 'Night', 'off', 'Morning', 'Night']
for i in range(len(b)): # loop through all indexes of elements in "b"
if b[i] == 'off' and a[i]: # replace element, if it's "off" and corresponding element in "a" is not empty
b[i] = a[i]
print(b)
Output:
['Sick', 'Mid 1', 'off', 'Night', 'Sick', 'Morning', 'Night']

Related

python3 - check element is actually in list

for example i have excel header list like this
excel_headers = [
'Name',
'Age',
'Sex',
]
and i have another list to check againt it.
headers = {'Name' : 1, 'Age': 2, 'Sex': 3, 'Whatever': 4}
i dont care if headers have whatever elements, i care only element in headers has excel_headers element.
WHAT I've TRIED
lst = all(headers[idx][0] == header for idx,
header in enumerate(excel_headers))
print(lst)
however it always return False.
any help? pleasse
Another way to do it using sets would be to use set difference:
excel_headers = ['Name', 'Age', 'Sex']
headers = {'Name' : 1, 'Age': 2, 'Sex': 3, 'Whatever': 4}
diff = set(excel_headers) - set(headers)
hasAll = len(diff) == 0 # len 0 means every value in excel_headers is present in headers
print(diff) #this will give you unmatched elements
Just sort your list, the results shows you a before and after
excel_headers = [
'Name',
'Age',
'Sex',
]
headers = ['Age' , 'Name', 'Sex']
if excel_headers==headers: print "YES!"
else: print "NO!"
excel_headers.sort()
headers.sort()
if excel_headers==headers: print "YES!"
else: print "NO!"
Output:
No!
Yes!
Tip: this is a good use case for a set, since you're looking up elements by value to see if they exist. However, for small lists (<100 elements) the difference in performance isn't really noticeable, and using a list is fine.
excel_headers = ['Name', 'Age', 'Sex']
headers = {'Name' : 1, 'Age': 2, 'Sex': 3, 'Whatever': 4}
result = all(element in headers for element in excel_headers)
print(result) # --> True

Make key lowercase in List of Dictionaries (Python3)

Been looking through Stackoverflow and documentations for 2 days now, I am a beginner, and I just can't progress. I am using Python 3.8.
I have a list of dictionaries:
books = [{'Type': 'Book', 'Date': '2011', 'Publication Year': '2011', 'Place Published': 'New York', 'Publisher': 'Simon & Schuster', 'Author': 'Walter Isaacson', 'ISBN': '978-1-4516-4853-9', 'Title': 'Test Steve Jobs'}, {'Type': 'Book', 'Date': '2001', 'Publication Year': '2001', 'Place Published': 'Oxford', 'Publisher': 'Oxford University press', 'Author': 'Peter Hall', 'ISBN': '978-0-19-924775-2', 'Title': 'Test Varieties of capitalism: the institutional foundations of comparative advantage'}]
print(books)
I want to make the key "Type" into a lowercase "type".
But with the following List Comprehension it somehow makes the key to a value and vice versa.
lower_list = [ { v:k.lower() for k,v in d.items() } for d in books ]
print(lower_list)
I end up with [{'Book': 'type',.... when it should be [{'type': 'Book',....
I am struggling with understanding the list comprehension syntax still, so would be grateful for 1. somebody explaining what my list comprehension does in plain English and 2. how to change it to achieve what I am looking for. :)
Thank you!
So your first problem:
lower_list = [ { k.lower():v for k,v in d.items() } for d in books ] ?
You was inverting key and values.
Your last question how to skip lowercasing the ISBN key:
[ { k if k is "ISBN" else k.lower():v.lower() for k,v in d.items()} for d in books ]
But you should consider using a for loop: if your need more operations or conditions, it would start to be difficult to modify further.
my_final_books = []
for d in books:
for k,v in d.items():
if k is "ISBN":
key = k
else:
key = k.lower()
# or ternary form key = k if k is "ISBN" else k.lower()
my_final_books.append({key:v})
# do more logic here

converting a file into dict

my_file = "The Itsy Bitsy Spider went up the water spout.
Down came the rain & washed the spider out.
Out came the sun & dried up all the rain,
And the Itsy Bitsy Spider went up the spout again. "
Expected output:
{'the': ['itsy', 'water', 'rain', 'spider', 'sun', 'rain', 'itsy', 'spout'], 'itsy': ['bitsy', 'bitsy'], 'bitsy': ['spider', 'spider'], 'spider': ['went', 'out', 'went'], 'went': ['up', 'up'], 'up': ['the', 'all', 'the'], 'water': ['spout'], 'spout': ['down', 'again'], 'down': ['came'], 'came': ['the', 'the'], 'rain': ['washed', 'and'], 'washed': ['the'], 'out': ['out', 'came'], 'sun': ['dried'], 'dried': ['up'], 'all': ['the'], 'and': ['the'], 'again': []}
My code:
import string
words_set = {}
for line in my_file:
lower_text = line.lower()
for word in lower_text.split():
word = word.strip(string.punctuation + string.digits)
if word:
if word in words_set:
words_set[word] = words_set[word] + 1
else:
words_set[word] = 1
You can reproduce your expected results with a few concepts:
Given
import string
import itertools as it
import collections as ct
data = """\
The Itsy Bitsy Spider went up the water spout.
Down came the rain & washed the spider out.
Out came the sun & dried up all the rain,
And the Itsy Bitsy Spider went up the spout again.
"""
Code
def clean_string(s:str) -> str:
"""Return a list of lowered strings without punctuation."""
table = str.maketrans("","", string.punctuation)
return s.lower().translate(table).replace(" ", " ").replace("\n", " ")
def get_neighbors(words:list) -> dict:
"""Return a dict of right-hand, neighboring words."""
dd = ct.defaultdict(list)
for word, nxt in it.zip_longest(words, words[1:], fillvalue=""):
dd[word].append(nxt)
return dict(dd)
Demo
words = clean_string(data).split()
get_neighbors(words)
Results
{'the': ['itsy', 'water', 'rain', 'spider', 'sun', 'rain', 'itsy', 'spout'],
'itsy': ['bitsy', 'bitsy'],
'bitsy': ['spider', 'spider'],
'spider': ['went', 'out', 'went'],
'went': ['up', 'up'],
'up': ['the', 'all', 'the'],
'water': ['spout'],
'spout': ['down', 'again'],
'down': ['came'],
'came': ['the', 'the'],
'rain': ['washed', 'and'],
'washed': ['the'],
'out': ['out', 'came'],
'sun': ['dried'],
'dried': ['up'],
'all': ['the'],
'and': ['the'],
'again': ['']}
Details
clean_string
You can use any number of ways to remove punctuation. Here we use a translation table to replace most of the punctuation. Others are directly removed via str.replace().
get_neighbors
A defaultdict makes a dict of lists. A new list value is made if a key is missing.
We make the dict by iterating two juxtaposed word lists, one ahead of the other.
These lists are zipped by the longest list, filling the shorter list with an empty string.
dict(dd) ensures a simply dict is returned.
If you solely wish to count words:
Demo
ct.Counter(words)
Results
Counter({'the': 8,
'itsy': 2,
'bitsy': 2,
'spider': 3,
'went': 2,
'up': 3,
'water': 1,
'spout': 2,
'down': 1,
'came': 2,
'rain': 2,
'washed': 1,
'out': 2,
'sun': 1,
'dried': 1,
'all': 1,
'and': 1,
'again': 1})

How to solve ValueError when testing truth value of Dataframe contents? Python

I have a Dataframe that looks like this.
done sentence 3_tags
0 0 ['What', 'were', 'the', '...] ['WP', 'VBD', 'DT']
1 0 ['What', 'was', 'the', '...] ['WP', 'VBD', 'DT']
2 0 ['Why', 'did', 'John', '...] ['WP', 'VBD', 'NN']
...
For each row I want to check if the list in column '3_tags' is on a list temp1, as follows:
a = pd.read_csv('sentences.csv')
temp1 = [ ['WP', 'VBD', 'DT'], ['WRB', 'JJ', 'VBZ'], ['WP', 'VBD', 'DT'] ]
q = a['3_tags']
q in temp1
For the first sentence in row 0, the value of '3_tags' = ['WP', 'VBD', 'DT'] which is in temp1 so I expect the result of the above to be:
True
However, I get this error:
ValueError: Arrays were different lengths: 1 vs 3
I suspect that there is some problem with the datatype of q:
print(type(q))
<class 'pandas.core.series.Series'>
Is the problem that q is a Series and temp1 contains lists? What should I do to get the logical result 'True' ?
You want those lists to be tuples instead.
Then use pd.Series.isin
*temp1, = map(tuple, temp1)
q = a['3_tags'].apply(tuple)
q.isin(temp1)
0 True
1 True
2 False
Name: 3_tags, dtype: bool
However, it appears that the '3_tags' column consists of strings that look like lists. In this case, we want to parse them with ast.literal_eval
from ast import literal_eval
*temp1, = map(tuple, temp1)
q = a['3_tags'].apply(lambda x: tuple(literal_eval(x)))
q.isin(temp1)
0 True
1 True
2 False
Name: 3_tags, dtype: bool
Setup1
a = pd.DataFrame({
'done': [0, 0, 0],
'sentence': list(map(str.split, ('What were the', 'What was the', 'Why did John'))),
'3_tags': list(map(str.split, ('WP VBD DT', 'WP VBD DT', 'WP VBD NN')))
}, columns='done sentence 3_tags'.split())
temp1 = [['WP', 'VBD', 'DT'], ['WRB', 'JJ', 'VBZ'], ['WP', 'VBD', 'DT']]
Setup2
a = pd.DataFrame({
'done': [0, 0, 0],
'sentence': list(map(str.split, ('What were the', 'What was the', 'Why did John'))),
'3_tags': list(map(str, map(str.split, ('WP VBD DT', 'WP VBD DT', 'WP VBD NN'))))
}, columns='done sentence 3_tags'.split())
temp1 = [['WP', 'VBD', 'DT'], ['WRB', 'JJ', 'VBZ'], ['WP', 'VBD', 'DT']]

Python3 how to add string to integer within a list

I am trying to calculate items within list, adding together string and integer.
Function does not work:
x_list = ['string', '100', 'string']
def calculate_str_and_int():
str_x = x_list[1]
sum_x = int(str_x) + 200
print(sum_x)
Expected output:
['string', 300, 'string']
Thank you in advance!
You should re-assign the value in position 1 to the newly calculated value, like e.g:
x_list = ['string', '100', 'string']
def calculate_str_and_int():
str_x = x_list[1]
sum_x = int(str_x) + 200
x_list[1] = sum_x
print(x_list)
calculate_str_and_int()
This will print:
['string', 300, 'string']

Resources