Инициализация списка к известному числу элементов в Python [дубликат]

AsyncStorage

Обычно для использования AsyncStorage вы сначала импортируете его в начало файла, в документации сказано, что вы должны импортировать его следующим образом:

import { AsyncStorage } from 'react-native';

Что вы можете увидеть здесь https://facebook.github.io/react-native/docs/asyncstorage

Очевидно, вам следует удалить предыдущий оператор импорта

import { AsyncStorage } from 'AsyncStorage'; 

[ 1135], если оставить его, вызовет конфликт имен.

Сохранение в AsyncStorage

Сохранение в AsyncStorage - асинхронная задача, поэтому вы должны использовать функцию async/await, что означает, что вы должны обновить свою функцию storeData(). Вы можете посмотреть документацию https://facebook.github.io/react-native/docs/asyncstorage , чтобы узнать, как это сделать.

storeData = async () => {
  const {a} = this.state;
  let  mynum = a;
  try {
    await AsyncStorage.setItem('array', mynum)
    Alert("Saved");
 } catch (err) {
    console.warn(err);
 } 
}

Установка состояния

Далее выглядит, что вы можете оказаться в состоянии гонки, когда вы устанавливаете состояние. SetState требуется время, чтобы установить состояние элемента. Поэтому, когда вы звоните

this.setState({ b: this.state.a });

, состояние, возможно, фактически не было установлено к тому времени, когда вы звоните

this.storeData();

, ведущему к неверное значение хранится в AsyncStorage.

Чтобы преодолеть это, есть несколько способов справиться с этим

  1. Использовать setState с обратным вызовом
  2. Передать переменную для сохранения в качестве параметра [ 1111]

Использование setState с обратным вызовом

В этой статье довольно подробно рассказывается об использовании setState с обратным вызовом https://medium.learnreact.com/setstate- принимает-a-callback-1f71ad5d2296 , однако вы можете изменить свой onPressButton на что-то вроде этого

onPressButton = () => {
  if (this.state.a == this.state.aa) {     
    this.setState({ b: this.state.a }, async () => { await this.storeData(); });
  } else {
    Alert("Try Again");
  }
}

Это будет гарантировать, что this.storeData() не будет работать, пока состояние не будет обновлено.

Передать переменную для хранения в качестве параметра

Для этого требуется рефакторинг функции storeData() для получения параметра

storeData = async (mynum) => {
  try {
    await AsyncStorage.setItem('array',mynum)
    Alert("Saved");
 } catch (err) {
    console.warn(err);
 } 
}

Теперь, чтобы использовать эту функцию, мы должны обновить your onPressButton, обратите внимание, что мы передаем значение, которое мы хотим сохранить, в storeData, что означает, что нам больше не нужно обращаться к нему из состояния внутри storeData

onPressButton = async () => {
  if (this.state.a == this.state.aa) {     
    this.setState({ b: this.state.a });
    await this.storeData(this.state.a);
  } else {
    Alert("Try Again");
  }
}

Извлечение из AsyncStorage

Это также асинхронная задача и требует async/await. Чтобы получить строку, которую вы сохранили, все, что вам нужно сделать, это передать правильный ключ в функцию retrieveData

retrieveData = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    if (value !== null) {
      // We have data!!
      console.log(value);
      // do something with the value
    }
   } catch (error) {
     // Error retrieving data
   }
}
228
задан Tim Cooper 28 October 2011 в 11:46
поделиться

5 ответов

Первая вещь, которая приходит на ум для меня:

verts = [None]*1000

, Но необходимо ли действительно предварительно инициализировать его?

334
ответ дан Steve Losh 23 November 2019 в 03:47
поделиться

Вы могли сделать это:

verts = list(xrange(1000))

, Который дал бы Вам список 1 000 элементов в размере и который, оказывается, инициализируется со значениями от 0-999. Как list делает __len__ сначала для калибровки нового списка, это должно быть довольно эффективно.

4
ответ дан John Montgomery 23 November 2019 в 03:47
поделиться

Необходимо рассмотреть использование dict тип вместо предварительно инициализированного списка. Стоимость поиска по словарю является маленькой и сопоставимой со стоимостью доступа к произвольному элементу списка.

И при использовании отображения Вас может записать:

aDict = {}
aDict[100] = fetchElement()
putElement(fetchElement(), fetchPosition(), aDict)

И эти putElement функция может сохранить объект в любом данном положении. И если необходимо проверить, содержит ли набор элемент в данном индексе, это - больше Pythonic для записи:

if anIndex in aDict:
    print "cool!"

, Чем:

if not myList[anIndex] is None:
    print "cool!"

, Так как последний предполагает, что никакой реальный элемент в Вашем наборе может быть None. И если это происходит - Ваш код неправильно себя ведет.

И если Вам отчаянно нужны производительность и вот почему Вы пытаетесь предварительно инициализировать свои переменные, и написать самый быстрый возможный код - изменяют Ваш язык. Самый быстрый код не может быть написан в Python. Необходимо попробовать C вместо этого и обертки реализации для вызова предварительно инициализированного и предварительного скомпилированного кода из Python.

0
ответ дан Abgan 23 November 2019 в 03:47
поделиться

Не зная больше о проблемной области, трудно ответить на Ваш вопрос. Если Вы не уверены, что необходимо сделать что-то больше, pythonic способ инициализировать список:

verts = []

Вы на самом деле наблюдение проблемы производительности? Если так, каково узкое место производительности? Не пытайтесь решить проблему, которую Вы не имеете. Вероятно, что стоимость производительности для динамичного заполнения массива к 1 000 элементов абсолютно не важна к программе, которую Вы действительно пытаетесь записать.

класс массива полезен, если вещи в Вашем списке всегда будут определенным примитивным типом фиксированной длины (например, символ, интервал, плавание). Но, это не требует предварительной инициализации также.

-2
ответ дан user26294 23 November 2019 в 03:47
поделиться

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

import array
verts=array.array('i',(0,)*1000)

Для не питонистов термин (0,) * 1000 создает кортеж, содержащий 1000 нулей. Запятая заставляет python распознавать (0) как кортеж,

70
ответ дан 23 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: