как найти индекс его предыдущего появления на python?

#python-3.x #list #dictionary

#python-3.x #Список #словарь

Вопрос:

(я только что отредактировал вопрос с помощью нескольких строк ввода) Для каждого слова из этого текста найдите индекс его предыдущего появления в тексте. Индекс первого слова равен 0. Если слово встречается в первый раз, выведите -1.

например: ввод: (4 строки ввода)

 She sells sea shells on the sea shore;
The shells that she sells are sea shells I'm sure.
So if she sells sea shells on the sea shore,
I'm sure that the shells are sea shore shells.
  

вывод :

-1 -1 -1 -1 -1 -1 2 -1 -1 3 -1 -1 1 -1 6 9 -1 -1 -1 -1 11 12 14 15 4 5 22 -1 16 -1 10 25 23 13 26 -1 -1

Она [0] продает [1] морские [2] раковины [3] на [4] [5] морском [6] берегу [7] …

Для sea на 6-й позиции предыдущее появление было на позиции 2.

Я пытаюсь использовать метод get, но теперь уверен, как получить значение индекса через get()

мой код: (мне нужно взять эти строки из входных данных)

 while True:
   ans = input().split()

   if len(ans)==0:
       break
   else:
       lst = [-1 if i == ans.index(ans[i]) else i-ans[:i][::-1].index(ans[i])-1 for i in range(len(ans))]
       print(*lst)
  

Комментарии:

1. s = 'She sells sea on on the sea shore sea' . Каков ожидаемый результат здесь?

2. я думаю, что это должно быть -1 -1 -1 -1 -1 2 -1 6

3. Разве это не должно быть -1 -1 -1 -1 3 -1 2 -1 6 ?

4. ваше право, должно быть -1 -1 -1 3 -1 2 -1 6

5. print(lst) должен выполнить задание. Какая-либо конкретная причина print(*lst) , по которой используется?

Ответ №1:

Вы можете использовать понимание списка для итерации слов:

 s = 'She sells sea shells on the sea shore by shells sea'.split()
lst = [-1 if i == s.index(s[i]) else i-s[:i][::-1].index(s[i])-1 for i in range(len(s))]

print(lst)
  

Вывод

 [-1, -1, -1, -1, -1, -1, 2, -1, -1, 3, 6]
  

— Обновить —

split() также работает для многострочных строк, поэтому можно использовать тот же код:

 s = '''
She sells sea shells on the sea shore;
The shells that she sells are sea shells I'm sure.
So if she sells sea shells on the sea shore,
I'm sure that the shells are sea shore shells.
'''

print(repr(s))  # confirm newline characters

s = s.split()

lst = [-1 if i == s.index(s[i]) else i-s[:i][::-1].index(s[i])-1 for i in range(len(s))]

print(lst)
  

Вывод

 "nShe sells sea shells on the sea shore;nThe shells that she sells are sea shells I'm sure.nSo if she sells sea shells on the sea shore,nI'm sure that the shells are sea shore shells.n"
[-1, -1, -1, -1, -1, -1, 2, -1, -1, 3, -1, -1, 1, -1, 6, 9, -1, -1, -1, -1, 11, 12, 14, 15, 4, 5, 22, -1, 16, -1, 10, 25, 23, 13, 26, -1, -1]
  

— Обновление # 2 —

Если вы хотите, чтобы пользователь вводил каждую строку отдельно, вы можете использовать список для сбора полного текста.

 txt = []

i = '-'
while i:
   i = input('Enter line or return to end: ')
   txt.append(i)
   
s = ' '.join(txt).split()

lst = [-1 if i == s.index(s[i]) else i-s[:i][::-1].index(s[i])-1 for i in range(len(s))]

print(lst)
  

Вывод

 Enter line or return to end: She sells sea shells on the sea shore;
Enter line or return to end: The shells that she sells are sea shells I'm sure.
Enter line or return to end: So if she sells sea shells on the sea shore,
Enter line or return to end: I'm sure that the shells are sea shore shells.
Enter line or return to end:
[-1, -1, -1, -1, -1, -1, 2, -1, -1, 3, -1, -1, 1, -1, 6, 9, -1, -1, -1, -1, 11, 12, 14, 15, 4, 5, 22, -1, 16, -1, 10, 25, 23, 13, 26, -1, -1]
  

— Обновление # 3 —

Это генерирует результат с использованием объекта defaultdict:

 from collections import defaultdict

s = '''
She sells sea shells on the sea shore by shells sea
'''
words = s.split()

idx = [(w,i) for i,w in enumerate(words)]  # word, index

d = defaultdict(list) # each element is empty list

for k, v in idx:
    d[k].append(v)  # get word indexes

print(d)  # {'She': [0], 'sells': [1], 'sea': [2, 6, 10], 'shells': [3, 9], 'on': [4], 'the': [5], 'shore': [7], 'by': [8]})

lst = [-1] * len(words)  # default -1

for k,v in d.items():
   if len(v) > 0:  # word appears more than once
      for i in range(1,len(v)):  # iterate indexes
          lst[v[i]] = v[i-1]

print(lst)  # [-1, -1, -1, -1, -1, -1, 2, -1, -1, 3, 6]
  

Комментарии:

1. s = 'She sells sea on on the sea shore sea' . Это может не дать предыдущего появления для последнего слова sea , которое равно 6

2. @Mike67 Привет, можете ли вы взглянуть на мой код (который скопировал ваше решение), дайте мне знать, почему это не сработало. Спасибо

3. Я отредактировал ваш вопрос, чтобы исправить отступы. Кажется, он работает правильно. Вы хотите, чтобы все входные данные были объединены в одну строку?

4. @Mike67 поскольку мне нужно вводить строку за строкой, если вы попробуете мой код, введите первую строку, затем нажмите enter, затем введите вторую строку, …. введите четвертую строку, нажмите enter и снова нажмите enter, чтобы завершить ввод, тогда вывод -1, -1, -1, -1, -1, -1, -1, -1, -1

5. второе редактирование работает для моего случая, спасибо. я думаю, что мне еще долго учиться на python

Ответ №2:

Вот один из способов сделать это (пример в IPython):

 In [1]: txt = "She sells sea shells on the sea shore"
Out[1]: 'She sells sea shells on the sea shore'

In [2]: words = txt.split()
Out[2]: ['She', 'sells', 'sea', 'shells', 'on', 'the', 'sea', 'shore']

In [3]: seen = {}
Out[3]: {}

In [4]: indexes = []
Out[4]: []

In [5]: for w in words:
   ...:     if w not in seen:
   ...:         seen[w] = 0
   ...:         indexes.append(-1)
   ...:     else:
   ...:         seen[w]  = 1
   ...:         indexes.append(seen[w]   1)
   ...:         

In [6]: indexes
Out[6]: [-1, -1, -1, -1, -1, -1, 2, -1]
  

Комментарии:

1. Это не решает проблему для всех тестовых наборов.

2. Это потому, что их еще не было, когда я писал это.

Ответ №3:

 s = 'She sells sea shells on the sea shore sea shells'
l = list(s.split())
res = []
curr_latest={}
for i in range(len(l)):
    if l[i] in curr_latest:
        res.append(curr_latest[l[i]])
    else:
        res.append(-1)
    curr_latest[l[i]]=i
print(res)
print(curr_latest)
  

Вы можете использовать индексный метод списка, чтобы получить первое вхождение элемента

Комментарии:

1. Не будет работать для ввода s = 'She sells sea on on the sea shore sea' . OP нужен индекс появления preiovus, а не первый.

Ответ №4:

Прежде всего, нет необходимости в цикле while. Во-вторых, оператор ans = list(input().split()) нет необходимости писать list(.. ..) . Split() возвращает только в формате списка.

теперь вот мое решение:

 lis = []
t_lis = []
ans = input().split()
print(ans)
if len(ans) == 0:
    print("RECEIEVD NO TEXT")
else:
    for word in ans:
        if word not in t_lis:
            lis.append(-1)
            t_lis.append(word)
        else:
            lis.append(ans.index(word))
print(lis)
  

Я пытался не изменять ваш логический формат.
Надеюсь, это помогло вам, и сегодня вы узнали что-то новое.

Комментарии:

1. Пожалуйста, внимательно посмотрите на вопрос. Это не относится ко всем тестовым сценариям.

Ответ №5:

Просто используйте традиционный for цикл:

 string = 'She sells sea shells on the sea shore'

lst = string.split(' ')

existing = []

for elem in lst:
    if existing.count(elem) == 0:
        print(f"{elem} = -1")
    else:
        indices = [i for i, x in enumerate(lst) if x == elem]
        index = indices[existing.count(elem) - 1]
        print(f"{elem} = {index}")
    existing.append(elem)
  

Вывод:

 She = -1
sells = -1
sea = -1
shells = -1
on = -1
the = -1
sea = 2
shore = -1
  

Комментарии:

1. Нам нужно предыдущее появление, а не первое появление слова.

2. Что вы имеете в виду под этим?

3. s = 'She sells sea on on the sea shore sea' . Для последнего слова sea оно должно давать 6 вместо 2

4. Почему он должен давать 6? Он должен давать только 3, поскольку слово sea встречается в строке только 3 раза.

5. OP нужен «индекс» «предыдущего появления» слова. Не «количество» его.