1

In the following code,

splits     = [(word[:i], word[i:])    for i in range(len(word) + 1)]
deletes    = [L + R[1:]               for L, R in splits if R]

for a given word, what does the if R mean in the last list comprehension?

Return L+R[1:] for every L,R combination in splits if R what? Exists? Is that a necessary check?

caesar
  • 185
  • 4
  • 1
    If R is not empty. – Daniel Roseman Sep 04 '19 at 13:18
  • `if [1,2,3,4]` evaluates to `True`, `if []` evaluates to `False` – Gsk Sep 04 '19 at 13:21
  • In the case where `i` is at its maximum value, `L` will be the entire word, and `R` will be empty. If this wasn't special-cased, `L + R[1:]` would be the entire word, and not the word with a character deleted as all of the other elements of `deletes` are. – jasonharper Sep 04 '19 at 13:28
  • And anyway [pep 8](https://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-and-statements) does not recommend to write an expression with that spacing – Gsk Sep 04 '19 at 13:28

3 Answers3

2

you can have a look (assume that your word is a string):

word = 'my_word'
print([(word[:i], word[i:])    for i in range(len(word) + 1)])

output:

[('', 'my_word'),
 ('m', 'y_word'),
 ('my', '_word'),
 ('my_', 'word'),
 ('my_w', 'ord'),
 ('my_wo', 'rd'),
 ('my_wor', 'd'),
 ('my_word', '')]

you can see that your last element has an empty string if you do not check for your R since you are using slicing(R[1:]), you will get: IndexError: string index out of range, so yes it is necessary to check in this case

if R is the way the checking is happing inside the list comprehension, the same logic as in a normal if statement.

you can have a look here to read more about if/else inside list comprehension

kederrac
  • 16,819
  • 6
  • 32
  • 55
1

The expression following if is evaluated in a boolean context, and the current value from splits is only used if that evaluation is true. In the case of a list, empty lists are considered False, all others True. The comprehension is equivalent to

deletes = []
for L, R in splits:
    if R != []:
        deletes.append(L + R[1:])
chepner
  • 497,756
  • 71
  • 530
  • 681
1

To be honest I did not understand your questions but I think this would help you understand the Python comprehension syntax.

You can place your if before 'for' keyword or after it.
1) Case 1: if is before 'for' statement.
Use this syntax if you want to put one element per each loop iteration. You use this to change value calculation method.

list_variable = [VALUE_CASE_TRUE if STATEMENT else VALUE_VASE_FALSE for LOOP_VALUE in VALUES_RANGE] # pseudocode here
# Example duplicate even values, but put odd values unchanged:
case_1 = [i if i&1 else 2*i for i in range(10)] # check this out, I bet you would get the point
# you CANNOT do like that though, else is MANDATORY:
case_1 = [i if i&1 for i in range(10)] # invalid syntax

2) Case 2: if is after 'for' keyword.
Use this syntax if you want to put value only under some condition.

list_variable = [VALUE for LOOP_VALUE in VALUES_RANGE if STATEMENT] # pseudocode here
# Example place only odd values into the new list:
case_2 = [i for i in range(10) if i&1]
Maciek
  • 463
  • 8
  • 22