Is there a python special character for a blank value? - python

I don't know how to ask this so I'm going to explain what I'm doing instead. I'm trying to search a list of lists with only 2 values. The first value I don't care about the second how ever I need to check and if it exsists I need the first value. Example
list = [[1,'text1'],[1,'text2'],[3,'text3'],[2,'text4']]
so basically I need to know if there is a character like % or ! that when used in find basically means any value. Link find(!,'text2') would get me the value of 1. (i know that wouldn't work like that). Ik I have the option of searching just the second value in lists but that's unecessary code if there is a special character as such.

There is no specific character or value for that, but you can either create your own sentinel object or you can use None for this. Just make sure to use is to detect it within your code.
# fmod.py
Any = object()
def find(first=Any, second=Any):
if first is Any:
...
...
import fmod
fmod.find(None, 'text2')
fmod.find(fmod.Any, 'text2')

You can do this with a list comprehension:
def findit(word, lst):
return [el[0] for el in lst if el[1] == word][0]

Try None value.
You can read more information about it here: Python 3 Constrants

When you say "the second how ever I need to check and if it exists I need the first value", I'm thinking you need to check if the second value is a) there (if the list has two elements) and b) of nonzero length (assuming they'll always be strings). This leads me to:
list_to_search = [[1,'text1'],[1,'text2'],[3,'text3'],[2,'text4'], [3], [4, '']]
firsts_with_seconds = [item[0] for item in list_to_search
if len(item) > 0 and len(item[1]) > 0]

Related

Assigning two values to a variable

I will try and explain this as well as possible without giving too many details on what I'm trying to do.
I have a website Website1 with a product x that has a value of 1
I have another website Website2 with the same product x that has a value of 2.
The product "x" has two values that need to be paired. Does this happen using a tuple?
x = [1, 2]
On Website2 I need to check a list of line items one by one in a loop. When it finds product x and it matches the joined value of 2 from Website1 in the tuple, I need to then perform a function to change the fulfillment value, the move onto the next line item to perform the next check. Here's what I have so far and I'm not even certain if the logic is anywhere close.
x = [1, 2]
if Website1 == x:
LineItem.find_element_by_xpath('./td[4]/div/div/input').clear()
time.sleep(2)
LineItem.find_element_by_xpath('./td[4]/div/div/input').send_keys("1")
else:
LineItem.find_element_by_xpath('./td[4]/div/div/input').clear()
time.sleep(2)
LineItem.find_element_by_xpath('./td[4]/div/div/input').send_keys("0")
Yes, you can easily use tuples to assign two values to a variable (the entire tuple is being assigned to the variable):
x = (val1, val2)
x[0] == val1 # True
x[1] == val2 # True
Side note:
[] defines a list, not a tuple. The latter is the immutable variant of the former
You should use tuples.
x = (1, 2)
To get the values from tuples you simply do:
x[0] to get the first value, x[1] for the next and so on.
You can use a tuple but you don't have to. It's just one way to do it. What you have in []s is an array. You can use that also and if you add a third+ website, you won't have to change the data structure, you'll just add a new value, e.g. x = [1, 2, 3] so having the array makes it easier to expand later vs a tuple.
Now to the code. It's kinda hard to understand your logic without more explanation but this should address your problem (and simplify your code).
You will notice that both the if and else block have basically the same code. The only difference is "1" vs "0" in the send_keys(). You should do some reading on DRY and DRY practices but the core concept is Don't Repeat Yourself. Pull the repeated lines out into a method called set_fulfillment_value() (You might want to give it a more appropriate name).
def set_fulfillment_value(value)
LineItem.find_element_by_xpath('./td[4]/div/div/input').clear()
# time.sleep(2) # this is a bad practice and should be removed (it likely isn't needed here anyway)
LineItem.find_element_by_xpath('./td[4]/div/div/input').send_keys(value)
Use the if to set the value to be sent and then pass that into the method.
x = [1, 2]
value = None
if Website1 == x[0]:
value = "1"
else:
value = "0"
set_fulfillment_value(value)
NOTE: I know naming is hard but you should work on better variable names. Website1 sounds like it might be better named something like product? Also, LineItem isn't very python-y. line_item would probably be better.
myValues = (a, b, c)
This will create a tuple, in which you can store multiple values.
To get the different values, just use myValues[0] to get the first element, for example.

Delete elements of a List, using a condition

Hello I'm learning to program in Python to manipulate data bases and I can't make this simple task. Please someone help me.
I have this list
CIS=['4998200lp','2159140lp','02546or']
I want to get this result:
CIS=['4998200lp','2159140lp','2546or']
I was trying something like:
for x in CIS:
izq= x[:1]
if izq == 0:
CIS=[x.replace(x[:1],'') for x in CIS]
print (CIS)
I just want to delete the first element of every string for the condition izq == 0.
Your description doesn't match your example input/output which also differs from your code.
Based on the example input/output, I suspect what you're trying to do is strip a single leading 0 from any string that starts with 0. And that's not too bad, but you can't do it in a for loop without having an index to assign back to. For that, you can use enumerate:
for i, x in enumerate(CIS):
if x.startswith('0'): # or x[:1] == '0' if you really prefer
CIS[i] = x[1:]
Alternatively, you can use a list comprehension to replace CIS:
CIS = [x[1:] if x.startswith('0') else x for x in CIS]
and to mutate in place (rather than making a new list), use the same comprehension but assign to the full slice, which makes it behave like the spelled out loop in the first example:
CIS[:] = [x[1:] if x.startswith('0') else x for x in CIS]
The difference between examples #1/#3 and example #2 occurs if CIS was passed as an argument to a function, or otherwise is referenced in multiple places. In #1/#3, it's mutating the list in place, so all references will see the updates, in #2, it's reassigning CIS, but leaving the original list unchanged; if other references exist, they won't appear changed.
Note: If the goal is to remove all leading 0s, then use str.lstrip, e.g.:
CIS = [x.lstrip('0') for x in CIS]
with similar adaptations for the other approaches. You don't even need to test for the presence of 0 in that case, as lstrip will return the str unmodified if it doesn't begin with 0.
If you are simply looking to remove the first zero of every string, utilize the startswith method. Also, don't look for an integer 0. Look for a string '0'.
Finally, you can simplify your implementation with doing this all in a comprehension, creating a new list with your new data:
[w[1:] if w.startswith('0') else w for w in CIS]
Outputs:
['4998200lp', '2159140lp', '2546or']
Just try to delete first character of every elements that starts with 0:
CIS=['4998200lp','2159140lp','02546or']
for i,v in enumerate(CIS):
if v.startswith('0'):
CIS[i] = v[1:]
CIS # ['4998200lp', '2159140lp', '2546or']
Actually your loop contained a very close approach to a working solution:
CIS=['4998200lp','2159140lp','02546or']
CIS=[x.replace(x[:1],'') for x in CIS]
but this would strip all first elements. To only replace them if they are '0' (notice that's not the same as the integer: 0) you need to incorporate you if ... else ... into the list-comprehension:
CIS=['4998200lp','2159140lp','02546or']
CIS=[x.replace(x[:1],'',1) if x[:1] == '0' else x for x in CIS ]
The if ... else ... syntax might be a bit strange but just try to read the code aloud: "Insert the replaced x if the first character is a zero or if not insert x, for every x in CIS".
The other answers contain much more sophisticated approaches but I just wanted to add this answer to give you a heads-up that you were on the right track!
But it's generally a bad idea to use a list-comprehension inside a for loop if they iterate over the same iterable. Mostly you just want one of them.

Trouble with my program to filter a list of strings

Please keep in mind that I am still fairly new to Python. I have this question which I have a fair bit of trouble understanding. I have made an attempt at this problem:
def Sample(A):
for i in range(len(A)):
if A == 1:
print A
elif A == (-1):
print A
Question:
Write a function where A is a list of strings, as of such print all the strings in A that start with '-1' or '1'
In your if and elif you are testing A, i.e. whether the whole list is equal to the value, which will never be True. Instead, test, each item in A. You can either stick with your index:
for i in range(len(A)):
if A[i] == ...
or, better, iterate over A directly:
for item in A:
if item == ...
Next, to test whether a string starts with a character, use str.startswith:
for item in A:
if item.startswith("1"):
...
Note that this uses the string "1", rather than the integer 1.
You're comparing if A equals 1 or -1, which is a bad start. You should be checking if i starts with either of those.
if i.startwith("1"):
Edit:
I completely edited my answer since I had misunderstood the question the first time.
You need to test for two cases does a_string in A start with '1' or start with -1.
Python offers a number ways to do this. First, is the string.startswith('something') method. This checks to see if the string startswith something you specified.
def Sample(A):
for each_string in A:
if each_string.startswith(('1','-1')):
print each_string

if a in list (I want to add something to the element in list) Python

As the topic states:
list = ["a", "b"]
element = "ac"
Can I use the:
if element in list:
If element is equal to the element in (list + "c")
Pseudocode to what I want to achieve:
if element in (list+c)
What is the best way to get this behavior in python?
Edit: I know there are many ways to get around this, but can this be done in one line as the code above.
More efficient would be:
if any(x+'c' == element for x in your_list):
as it avoids scanning through the list twice (once to make the "+c" versions, once to check if element is in the resulting list). It'll also "short-circuit" (that is, quickly move on) if it finds the element before going through the entire list.
P.S. - it's best not to name variables list, since that's already the name for the actual list type.
if element in [elem + 'c' for elem in my_list]:
# ...
Never a good practice to call a variable list (or int, float, map, tuple, etc.), because you are loosing those built-in types.
if element[0] in list:
You don't want to add "c" to every item in the list and check to see whether "ac" is in the resut; you want to check to see if the first letter of "ac" is in the list. It's the same thing except a lot easier.
if element[:-1] in list:
It is better to calculate the element without 'c'. So you are making just one calculation.

Python: removing specific lines from an object

I have a bit of a weird question here.
I am using iperf to test performance between a device and a server. I get the results of this test over SSH, which I then want to parse into values using a parser that has already been made. However, there are several lines at the top of the results (which I read into an object of lines) that I don't want to go into the parser. I know exactly how many lines I need to remove from the top each time though. Is there any way to drop specific entries out of a list? Something like this in psuedo-python
print list
["line1","line2","line3","line4"]
list = list.drop([0 - 1])
print list
["line3","line4"]
If anyone knows anything I could use I would really appreciate you helping me out. The only thing I can think of is writing a loop to iterate through and make a new list only putting in what I need. Anyway, thanlks!
Michael
Slices:
l = ["line1","line2","line3","line4"]
print l[2:] # print from 2nd element (including) onwards
["line3","line4"]
Slices syntax is [from(included):to(excluded):step]. Each part is optional. So you can write [:] to get the whole list (or any iterable for that matter -- string and tuple as an example from the built-ins). You can also use negative indexes, so [:-2] means from beginning to the second last element. You can also step backwards, [::-1] means get all, but in reversed order.
Also, don't use list as a variable name. It overrides the built-in list class.
This is what the slice operator is for:
>>> before = [1,2,3,4]
>>> after = before[2:]
>>> print after
[3, 4]
In this instance, before[2:] says 'give me the elements of the list before, starting at element 2 and all the way until the end.'
(also -- don't use reserved words like list or dict as variable names -- doing that can lead to confusing bugs)
You can use slices for that:
>>> l = ["line1","line2","line3","line4"] # don't use "list" as variable name, it's a built-in.
>>> print l[2:] # to discard items up to some point, specify a starting index and no stop point.
['line3', 'line4']
>>> print l[:1] + l[3:] # to drop items "in the middle", join two slices.
['line1', 'line4']
why not use a basic list slice? something like:
list = list[3:] #everything from the 3 position to the end
You want del for that
del list[:2]
You can use "del" statment to remove specific entries :
del(list[0]) # remove entry 0
del(list[0:2]) # remove entries 0 and 1

Categories