Implement remove method in for list - python

I'm trying to understand what the following function does, and in specific what does the if part is doing:
def remove(items, value):
new_items = []
found = False
for item in items:
if not found and item == value:
found = True
continue
new_items.append(item)
if not found :
raise ValueError('list.remove(x): x not in list')
return new_items
The statement if not found and item == value: and the trick of variable found . can someone specifically explain it?
Thanks, Now I understand the example code snippet above. And I can write code to implement my idea
My idea is to first make sure the value is in the initial list . then compare every item with that value, add the item which doesn't satisfy condition item != value to a new list new_items, finally return the new list.
def remove(items, value):
new_items = []
for item in items:
if item == value :
continue
else :
new_items.append(item)
if len(items) == len(new_items):
print("This value is not in the list")
return new_items

found is just a flag; while it's False (not found is True), you're checking each item against the target value. When you find a match, you set found to True, and bypass the item that matched (continue skips the rest of the body of the loop, returning to the top of the loop immediately, so append isn't called).
After that, not found is always False, and since and is a short-circuiting test, if the left hand side is False, then the right hand side isn't even checked. From there on, you just append all remaining items as you go. By using the flag and checking it first, you:
Avoid removing more than one copy of value from the newly created list
Avoid the work of comparing items once you've found a match (testing not somebool is the cheapest test available in Python beyond testing a compile time constant), speeding up the code a bit

Since found is initialized to be False it means that not found is evaluated to True, so while we're iterating the items and until we've found the item we're looking for, we'll compare each item == value and if it evaluates to True we'll enter the if body and execute two things:
modify the value of found to True: which means that from now on
we'll never enter that if block again
continue we'll "jump" over the part that adds this item that we
found
To sum it up: when we'll run into the first occurrence of value during iteration, we'll flip the value of the flag found and we'll skip the part that adds it to the new list. This will result in adding all the items but this one to the new-list.

Related

If statement on for-loop on strings not working despite meeting condition

I have a for loop on a list as I have shown with f below and I have a conditional statement where the first object of the list does not meet but the second and third object does. For some reason, the condition is not returning the desired result and I cannot understand why this is the case?
minimum working example
# containers
absolute_path_list = []
f = [ 'Documents/projects/packout_model/.venv/lib/python3.9/site-packages/numpy/core/tests/data/file1.csv',
'Documents/projects/packout_model/data/03-06-2022/csv_store/file2.csv',
'/Documents/projects/packout_model/data/03-06-2022/csv_store/file3.csv']
# loop over f to find files that meet our condition
for file in f:
if (file.find('csv_store') and file.find('03-06-2022')) and (file.find('packout_model') and file.endswith("csv")): # error here
absolute_path_list.append(file)
print(absolute_path_list) # print list of str objects that met condition
output being generated
[ 'Documents/projects/packout_model/.venv/lib/python3.9/site-packages/numpy/core/tests/data/file1.csv',
'Documents/projects/packout_model/data/03-06-2022/csv_store/file2.csv',
'/Documents/projects/packout_model/data/03-06-2022/csv_store/file3.csv']
desired output
['Documents/projects/packout_model/data/03-06-2022/csv_store/file2.csv',
'/Documents/projects/packout_model/data/03-06-2022/csv_store/file3.csv']
Edit:
solution to work around on answer
Using the answer provided I managed to write a workaround. Hope it helps.
def check_found(val: str=None, substring: str=None):
return not val.find(substring) == -1 # .find returns -1 if not found
for file in f:
print(check_found(file, 'csv_store'))
# result
False
True
True
In Python, bool(-1) evaluates to True.
The documentation of the str.find method says if the string is not found, then it returns -1
Hence, no matter if you find or not the needles you are looking for, your condition will always evaluates to True.
You may consider testing positivity of the result, or using the similar index method that raises an exception on failure.

Python linked list remove

When the remove_from_tail() method is called, the last element in the linked list is removed from the linked list. Your solution to this exercise will be a minimal implementation of the LinkedList class that contains the following methods: init(), print_all(), add() and remove_from_tail(). To complete the remove_from_tail() method, it might be useful to create a loop and use a "curr" reference to locate the last element in the list, but at the same time keep a "prev" reference to the previous Node in the chain. Once you have reached the end of the list, you can set the "next" field of the "prev" pointer to None to remove the last element. You can assume that there will be at least one element in the list when remove_from_tail() is called - however, if there is only one element, then you will need to set head to None when that element is removed.
EDIT:
I have change my code and got things right, however, there are still small things with error, and I can't seems to figure out why. This is my new code:
def remove_from_tail(self):
current = self.head
previous = current
while current.get_next() != None:
previous = current
current = current.get_next()
previous.set_next(None)
return current.get_data()
The error that has to be fixed:Sample2
The while-loop conditional handles only multiple-item lists. Try adding a condition to check for one-item lists before the while loop:
# Check for an empty list
...
# Check for one-item list
if current.get_next() == None:
data = current.get_data()
self.head = None
return data
# Multi item list
...

Is it possible to find out which condition is being met in a multi condition if then statement?

I'm working on a python/beautifulsoup web scraper. I'm searching for certain keywords, my statement looks like this:
if 'tribe' in entry or 'ai1ec' in entry or 'tfly' in entry:
print('Plugin Found!')
rating = easy
sheet.cell(row=i, column=12).value = rating
What I would like to do is find out which one of those keywords is making the statement true. My first instinct would be to write a nested loop to check but I wasn't sure if there was a way to capture the value that makes the statement true that would involve less code?
I would use a generator comprehension that I would pass to next with a default value. If the comprehension doesn't find anything, next returns the default value, else it returns the first found and stops there (kind of any, but which stores the result)
cases = ['tribe','allec','tfly']
entry = 'iiii allec rrrr'
p = next((x for x in cases if x in entry),None)
if p is not None:
print('Plugin Found!',p)
[EDIT: changed to only find first name]
for name in ('tribe', 'ailec', 'tfly'):
if name in entry:
print ('Name =', name)
print('Plugin Found!')
rating = easy
sheet.cell(row=i, column=12).value = rating
break

In Python how to make sure item in a list be processed successfully

I try this:
for k in keywords_list:
google_add = random.choice(google_adds_list)
url = make_up_url(google_add, k, False)
if scrape_keyword_count(k, useragent_list, url, result_dir):
keyword_count = scrape_keyword_count(k, useragent_list, url, result_dir)
all_keyword_count.append(keyword_count)
print '%s Finish. Removeing it from the list' % k
keywords_list.remove(k)
else:
print "%s may run into problem, removing it from list" % google_add
google_adds_list.remove(google_add)
with open(google_adds, 'w') as f:
f.write('\n'.join(google_adds_list))
I set up many reverse proxy server for google. the server list is google_add_list
I mean to search all the item in the list with the add i provide and get the result
If google block me, the scrape_keyword_count() will return None. then i
And I need to change to another add to do the search. but the script i wrote will skip the keyword no matter the scrape_keyword_count() success or not
I know removing an item within the for loop is dangerous i will improve this part later
The problem here is that you're modifying the list while iterating over it.
Use "for i in the_list[:]" instead. This will iterate over a copy of the list, fixing your "skipping" (missed elements) issue.
The for loop will use each item once... Your code looks fine... But I think you may not be returning the correct value in do_something_with
Try this:
for i in the_list:
value = do_something_with(i)
print bool(value)
if value:
the_list.remove(i)
<etc> <etc>
I think you may always be returning True from do_something_with
Perhaps:
new_list = []
for i in the_list:
if do_something_with(i):
continue
do_something_else(i)
new_list.append(i)
If do_something_with(i) succeeded then continue with the next item otherwise do_something_else(i).
You can't mutate a list while iterating over it. If the filtered list is needed, rather than removing elements from the old one produce a new one.

Check if Dictionary Values exist in a another Dictionary in Python

I am trying to compare values from 2 Dictionaries in Python. I want to know if a value from one Dictionary exists anywhere in another Dictionary. Here is what i have so far. If it exists I want to return True, else False.
The code I have is close, but not working right.
I'm using VS2012 with Python Plugin
I'm passing both Dictionary items into the functions.
def NameExists(best_guess, line):
return all (line in best_guess.values() #Getting Generator Exit Error here on values
for value in line['full name'])
Also, I want to see if there are duplicates within best_guess itself.
def CheckDuplicates(best_guess, line):
if len(set(best_guess.values())) != len(best_guess):
return True
else:
return False
As error is about generator exit, I guess you use python 3.x. So best_guess.values() is a generator, which exhaust for the first value in line['full name'] for which a match will not be found.
Also, I guess all usage is incorrect, if you look for any value to exist (not sure, from which one dictinary though).
You can use something like follows, providing line is the second dictionary:
def NameExists(best_guess, line):
vals = set(best_guess.values())
return bool(set(line.values()).intersection(vals))
The syntax in NameExists seems wrong, you aren't using the value and best_guess.values() is returning an iterator, so in will only work once, unless we convert it to a list or a set (you are using Python 3.x, aren't you?). I believe this is what you meant:
def NameExists(best_guess, line):
vals = set(best_guess.values())
return all(value in vals for value in line['full name'])
And the CheckDuplicates function can be written in a shorter way like this:
def CheckDuplicates(best_guess, line):
return len(set(best_guess.values())) != len(best_guess)

Categories

Resources