Delete elements of a List, using a condition - python

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.

Related

Python 3 Error Missunderstanding (IndexError)

Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)

How to delete the very last character from every string in a list of strings

I have the strings '80010', '80030', '80050' in a list, as in
test = ['80010','80030','80050']
How can I delete the very last character (in this case the very last digit of each string which is a 0), so that I can end up with another list containing only the first four digits/characters from each string? So end up with something like
newtest = ['8001', '8003', '8005']
I am very new to Python but I have tried with if-else statements, appending, using indexing [:-1], etc. but nothing seems to work unless I end up deleting all my other zeros. Thank you so much!
test = ["80010","80030","80050"]
newtest = [x[:-1] for x in test]
New test will contain the result ["8001","8003","8005"].
[x[:-1] for x in test] creates a new list (using list comprehension) by looping over each item in test and putting a modified version into newtest. The x[:-1] means to take everything in the string value x up to but not including the last element.
You are not so far off. Using the slice notation [:-1] is the right approach. Just combine it with a list comprehension:
>>> test = ['80010','80030','80050']
>>> [x[:-1] for x in test]
['8001', '8003', '8005']
somestring[:-1] gives you everything from the character at position 0 (inclusive) to the last character (exclusive).
Just to show a slightly different solution than comprehension, Given that other answers already explained slicing, I just go through at the method.
With the map function.
test = ['80010','80030','80050']
print map(lambda x: x[:-1],test)
# ['8001', '8003', '8005']
For more information about this solution, please read the brief explanation I did in another similar question.
Convert a list into a sequence of string triples
In python #Matthew solution is perfect. But if indeed you are a beginer in coding in general, I must recommend this, less elegant for sure but the only way in many other scenario :
#variables declaration
test = ['80010','80030','80050']
length = len(test) # for reading and writing sakes, len(A): length of A
newtest = [None] * length # newtest = [none, none, none], go look up empty array creation
strLen = 0 # temporary storage
#adding in newtest every element of test but spliced
for i in range(0, lenght): # for loop
str = test[i] # get n th element of test
strLen = len (str) # for reading sake, the lenght of string that will be spliced
newtest[i] = str[0:strLen - 1] # n th element of newtest is the spliced n th element from test
#show the results
print (newtest) # ['8001','8003','8005']
ps : this scripts, albeit not being the best, works in python ! Good luck to any programmer newcommer.
I had a similar problem and here is the solution.
List<String> timeInDays = new ArrayList<>();
timeInDays.add(2d);
timeInDays.add(3d);
timeInDays.add(4d);
I need to remove last letter in every string in-order to compare them. Below solution worked for me.
List<String> trimmedList = new ArrayList<>;
for(int i=0;i<timeInDays.size();i++)
{
String trimmedString = timeInDays.get(i).substring(0,name.length()-1);
trimmedList=add(trimmedString );
}
System.out.println("List after trimming every string is "+trimmedList);

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

Altering a list using append during a list comprehension

Caveat: this is a straight up question for code-golfing, so I know what I'm asking is bad practise in production
I'm trying to alter an array during a list comprehension, but for some reason it is hanging and I don't know why or how to fix this.
I'm dealing with a list of lists of indeterminite depth and need to condense them to a flat list - for those curious its this question. But at this stage, lets just say I need a flat list of all the elements in the list, and 0 if it is a list.
The normal method is to iterate through the list and if its a list add it to the end, like so:
for o in x:
if type(o)==type([]):x+=o
else:i+=o
print i
I'm trying to shorten this using list comprehension, like so.
print sum([
[o,x.append(o) or 0][type(o)==type([])]
for o in x
]))
Now, I know List.append returns None, so to ensure that I get a numeric value, lazy evaluation says I can do x.append(o) or 0, and since None is "falsy" it will evaulate the second part and the value is 0.
But it doesn't. If I put x.append() into the list comprehension over x, it doesn't break or error, or return an iteration error, it just freezes. Why does append freeze during the list comprehension, but the for loop above works fine?
edit: To keep this question from being deleted, I'm not looking for golfing tips (they are very educational though), I was looking for an answer as to why the code wasn't working as I had written it.
or may be lazy, but list definitions aren't. For each o in x, when the [o,x.append(o) or 0][type(o)==type([])] monstrosity is evaluated, Python has to evaluate [o,x.append(o) or 0], which means evaluating x.append(o) or 0, which means that o will be appended to x regardless of whether it's a list. Thus, you end up with every element of x appended to x, and then they get appended again and again and again and OutOfMemoryError
What about:
y = [element for element in x if type(element) != list or x.extend(element)]
(note that extend will flatten, while append will only add the nested list back to the end, unflattened).

Is there a python special character for a blank value?

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]

Categories