Анализ строк: разбиение строк на n частей по проценту слов - PullRequest
1 голос
/ 27 мая 2020

Мне нужно рассчитать длину каждой строки, включенной в список:

list_strings=["I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best","So many books, so little time.","In three words I can sum up everything I've learned about life: it goes on.","if you tell the truth, you don't have to remember anything.","Always forgive your enemies; nothing annoys them so much."]

, чтобы разделить каждую из них на три части:

  • 30% (первая часть)
  • 30% (вторая часть)
  • 40% (третья часть)

Я бы смог вычислить длину каждой строки в списке , но я не знаю, как каждую строку разбить на три части и сохранить их. Например: первое предложение "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best" имеет длину 201 (токенизация), поэтому мне нужно взять

  • 30% от 201 и сохранить эти слова в массив (первые 60 слов примерно);
  • 30% от оставшегося (т.е. следующие 60 слов);
  • наконец 40%, то есть последние 80 слов.

Я читал об использовании фрагментов, но понятия не имею, как их можно применить. Кроме того, мне нужно условие, которое может гарантировать, что я беру целые (элементы, такие слова не могут быть рассмотрены 1/2) слова, и я не выхожу за пределы длины.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Разделение текста по процентам от знаков препинания

def split_text(s):
  """ Partitions text into three parts
      in proportion 30%, 40%, 30%"""

  i1 = int(0.3*len(s))  # first part from 0 to i1
  i2 = int(0.7*len(s))  # 2nd for i1 to i2, 3rd i2 onward

  # Use isalpha() to check when we are at a punctuation
  # i.e. . or ; or , or ? " or ' etc.
  # Find nearest alphanumeric boundary
  # backup as long as we are in an alphanumeric
  while s[i1].isalpha() and i1 > 0:
    i1 -= 1

  # Find nearest alphanumeric boundary (for 2nd part)
  while s[i2].isalpha() and i2 > i1:
    i2 -= 1

  # Returns the three parts
  return s[:i1], s[i1:i2], s[i2:]


for s in list_strings:
  # Loop over list reporting lengths of parts
  # Three parts are a, b, c
  a, b, c = split_text(s)
  print(f'{s}\nLengths: {len(a)}, {len(b)}, {len(c)}')
  print()

Вывод

I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best
Lengths: 52, 86, 63

So many books, so little time.
Lengths: 7, 10, 13

In three words I can sum up everything I've learned about life: it goes on.
Lengths: 20, 31, 24

if you tell the truth, you don't have to remember anything.
Lengths: 15, 25, 19

Always forgive your enemies; nothing annoys them so much.
Lengths: 14, 22, 21

Вывод split_text

Код

for s in list_strings:
    a, b, c = split_text(s)
    print(a)
    print(b)
    print(c)
    print()

Результат

I'm selfish, impatient and a little insecure. I make
 mistakes, I am out of control and at times hard to handle. But if you can't handle me
 at my worst, then you sure as hell don't deserve me at my best

So many
 books, so
 little time.

In three words I can
 sum up everything I've learned
 about life: it goes on.

if you tell the
 truth, you don't have to
 remember anything.

Always forgive
 your enemies; nothing
 annoys them so much.

Захват разделов

result_a, result_b, result_c = [], [], []
for s in list_strings:
      # Loop over list reporting lengths of parts
      # Three parts are a, b, c
      a, b, c = split_text(s)
      result_a.append(a)
      result_b.append(b)
      result_c.append(c)
0 голосов
/ 27 мая 2020

В этом решении мы собираемся рассматривать слова по содержанию альфы и апострофа, используя это регулярное выражение:

[\w]+[']?[\w]*

Текст будет разбит по знакам препинания. Итак, если мы разделим « Я селфи sh, нетерпеливый и » в словах, это даст следующее:

["I'm", "selfish", "impatient", "and", "a"]

Затем мы получаем проценты списка строк и сохраняем эти слова в массив с 3 позициями в соответствии с perc_list, определенным в начале.

Вот код:

import re 
perc_list = [0.3, 0.3, 0.4] #tot must be 1
list_strings=["I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best","So many books, so little time.","In three words I can sum up everything I've learned about life: it goes on.","if you tell the truth, you don't have to remember anything.","Always forgive your enemies; nothing annoys them so much."]

for string in list_strings:
    ls = re.findall("[\w]+[']?[\w]*", string)
    idxl = [round(perc_list[0] * len(ls))]
    idxl.append(idxl[0] + round(perc_list[1] * len(ls)))
    arr_str = [ls[0:idxl[0]], ls[idxl[0]: idxl[1]], ls[idxl[1]:]]
    print (string, '\n ', idxl[0], idxl[1], len(ls), '\n ', "\n  ".join(str(i) for i in arr_str), '\n')

Вот результат:

enter image description here

...